112 lines
4.2 KiB
Java
112 lines
4.2 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import com.mojang.serialization.MapCodec;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.levelgen.feature.EndPlatformFeature;
|
|
import net.minecraft.world.level.material.Fluid;
|
|
import net.minecraft.world.level.portal.DimensionTransition;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import net.minecraft.world.phys.shapes.BooleanOp;
|
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
|
import net.minecraft.world.phys.shapes.Shapes;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
|
|
public class EndPortalBlock extends BaseEntityBlock implements Portal {
|
|
public static final MapCodec<EndPortalBlock> CODEC = simpleCodec(EndPortalBlock::new);
|
|
protected static final VoxelShape SHAPE = Block.box(0.0, 6.0, 0.0, 16.0, 12.0, 16.0);
|
|
|
|
@Override
|
|
public MapCodec<EndPortalBlock> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
protected EndPortalBlock(BlockBehaviour.Properties properties) {
|
|
super(properties);
|
|
}
|
|
|
|
@Override
|
|
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
|
return new TheEndPortalBlockEntity(pos, state);
|
|
}
|
|
|
|
@Override
|
|
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
|
return SHAPE;
|
|
}
|
|
|
|
@Override
|
|
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
|
|
if (entity.canUsePortal(false)
|
|
&& Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move(-pos.getX(), -pos.getY(), -pos.getZ())), state.getShape(level, pos), BooleanOp.AND)) {
|
|
if (!level.isClientSide && level.dimension() == Level.END && entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) {
|
|
serverPlayer.showEndCredits();
|
|
} else {
|
|
entity.setAsInsidePortal(this, pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public DimensionTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
|
|
ResourceKey<Level> resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END;
|
|
ServerLevel serverLevel = level.getServer().getLevel(resourceKey);
|
|
if (serverLevel == null) {
|
|
return null;
|
|
} else {
|
|
boolean bl = resourceKey == Level.END;
|
|
BlockPos blockPos = bl ? ServerLevel.END_SPAWN_POINT : serverLevel.getSharedSpawnPos();
|
|
Vec3 vec3 = blockPos.getBottomCenter();
|
|
float f = entity.getYRot();
|
|
if (bl) {
|
|
EndPlatformFeature.createEndPlatform(serverLevel, BlockPos.containing(vec3).below(), true);
|
|
f = Direction.WEST.toYRot();
|
|
if (entity instanceof ServerPlayer) {
|
|
vec3 = vec3.subtract(0.0, 1.0, 0.0);
|
|
}
|
|
} else {
|
|
if (entity instanceof ServerPlayer serverPlayer) {
|
|
return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, DimensionTransition.DO_NOTHING);
|
|
}
|
|
|
|
vec3 = entity.adjustSpawnLocation(serverLevel, blockPos).getBottomCenter();
|
|
}
|
|
|
|
return new DimensionTransition(
|
|
serverLevel, vec3, entity.getDeltaMovement(), f, entity.getXRot(), DimensionTransition.PLAY_PORTAL_SOUND.then(DimensionTransition.PLACE_PORTAL_TICKET)
|
|
);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
|
|
double d = pos.getX() + random.nextDouble();
|
|
double e = pos.getY() + 0.8;
|
|
double f = pos.getZ() + random.nextDouble();
|
|
level.addParticle(ParticleTypes.SMOKE, d, e, f, 0.0, 0.0, 0.0);
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState state) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
|
|
@Override
|
|
protected boolean canBeReplaced(BlockState state, Fluid fluid) {
|
|
return false;
|
|
}
|
|
}
|