82 lines
3.5 KiB
Java
82 lines
3.5 KiB
Java
|
package com.thebrokenrail.energonrelics.block.portal;
|
||
|
|
||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||
|
import com.thebrokenrail.energonrelics.config.HardcodedConfig;
|
||
|
import net.minecraft.block.Block;
|
||
|
import net.minecraft.block.BlockState;
|
||
|
import net.minecraft.block.Blocks;
|
||
|
import net.minecraft.entity.Entity;
|
||
|
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
|
||
|
import net.minecraft.server.command.TeleportCommand;
|
||
|
import net.minecraft.server.world.ServerWorld;
|
||
|
import net.minecraft.util.math.BlockPos;
|
||
|
import net.minecraft.util.math.Vec3d;
|
||
|
import net.minecraft.util.registry.RegistryKey;
|
||
|
import net.minecraft.world.Heightmap;
|
||
|
import net.minecraft.world.World;
|
||
|
|
||
|
import java.util.EnumSet;
|
||
|
|
||
|
class EnergyTeleporter {
|
||
|
private static void teleport(Entity entity, ServerWorld to, Vec3d pos) {
|
||
|
try {
|
||
|
TeleportCommand.teleport(null, entity, to, pos.getX(), pos.getY(), pos.getZ(), EnumSet.noneOf(PlayerPositionLookS2CPacket.Flag.class), entity.yaw, entity.pitch, null);
|
||
|
} catch (CommandSyntaxException ignored) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void teleport(ServerWorld world, Vec3d pos, BlockPos blockPos, Entity entity) {
|
||
|
BlockPos center = EnergyPortalBlock.getCenterPos(world, blockPos);
|
||
|
Vec3d offset = pos.subtract(Vec3d.ofBottomCenter(center));
|
||
|
|
||
|
RegistryKey<World> worldKey = world.getRegistryKey();
|
||
|
if (worldKey == World.OVERWORLD) {
|
||
|
teleportWithMultiplier(world, entity, center, offset, World.NETHER, 1d / HardcodedConfig.ENERGY_PORTAL_MULTIPLIER);
|
||
|
} else if (worldKey == World.NETHER) {
|
||
|
teleportWithMultiplier(world, entity, center, offset, World.OVERWORLD, HardcodedConfig.ENERGY_PORTAL_MULTIPLIER);
|
||
|
} else {
|
||
|
teleportToWorldSpawn(world, entity);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void teleportWithMultiplier(ServerWorld world, Entity entity, BlockPos center, Vec3d offset, RegistryKey<World> toKey, double multiplier) {
|
||
|
ServerWorld to = world.getServer().getWorld(toKey);
|
||
|
assert to != null;
|
||
|
|
||
|
float yMultiplier = (float) to.getDimensionHeight() / (float) world.getDimensionHeight();
|
||
|
int y = (int) (center.getY() * yMultiplier);
|
||
|
|
||
|
int x = (int) (center.getX() * multiplier);
|
||
|
int z = (int) (center.getZ() * multiplier);
|
||
|
|
||
|
BlockPos targetBlock = new BlockPos(x, y, z);
|
||
|
|
||
|
BlockPos start = targetBlock.add(-1, -1, -1);
|
||
|
for (int xPos = 0; xPos < 3; xPos++) {
|
||
|
for (int yPos = 0; yPos < 4; yPos++) {
|
||
|
for (int zPos = 0; zPos < 3; zPos++) {
|
||
|
BlockPos pos = start.add(xPos, yPos, zPos);
|
||
|
BlockState oldState = to.getBlockState(pos);
|
||
|
if (oldState.getHardness(world, pos) >= 0) {
|
||
|
Block block = yPos == 0 ? Blocks.OBSIDIAN : Blocks.AIR;
|
||
|
BlockState state = block.getDefaultState();
|
||
|
to.setBlockState(pos, state);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Vec3d target = Vec3d.ofBottomCenter(targetBlock).add(offset);
|
||
|
target = new Vec3d(target.getX(), Math.max(0, target.getY()), target.getZ());
|
||
|
|
||
|
teleport(entity, to, target);
|
||
|
}
|
||
|
|
||
|
private static void teleportToWorldSpawn(ServerWorld world, Entity entity) {
|
||
|
ServerWorld to = world.getServer().getWorld(World.OVERWORLD);
|
||
|
assert to != null;
|
||
|
BlockPos dest = to.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, to.getSpawnPos());
|
||
|
teleport(entity, to, Vec3d.ofBottomCenter(dest));
|
||
|
}
|
||
|
}
|