This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
EnergonRelics/src/main/java/com/thebrokenrail/energonrelics/block/portal/EnergyTeleporter.java

105 lines
4.6 KiB
Java
Raw Normal View History

2020-08-01 23:28:24 +00:00
package com.thebrokenrail.energonrelics.block.portal;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.thebrokenrail.energonrelics.config.HardcodedConfig;
2020-08-20 18:53:53 +00:00
import com.thebrokenrail.energonrelics.mixin.ServerPlayerEntityAccessor;
2020-08-01 23:28:24 +00:00
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;
2020-08-02 00:37:57 +00:00
import net.minecraft.server.network.ServerPlayerEntity;
2020-08-01 23:28:24 +00:00
import net.minecraft.server.world.ServerWorld;
2020-08-02 00:37:57 +00:00
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
2020-08-01 23:28:24 +00:00
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) {
2020-08-20 18:53:53 +00:00
if (entity instanceof ServerPlayerEntity) {
((ServerPlayerEntityAccessor) entity).setInTeleportationState(true);
}
2020-08-01 23:28:24 +00:00
try {
TeleportCommand.teleport(null, entity, to, pos.getX(), pos.getY(), pos.getZ(), EnumSet.noneOf(PlayerPositionLookS2CPacket.Flag.class), entity.yaw, entity.pitch, null);
2020-08-20 18:53:53 +00:00
} catch (CommandSyntaxException e) {
throw new RuntimeException(e);
}
if (entity instanceof ServerPlayerEntity) {
((ServerPlayerEntity) entity).networkHandler.syncWithPlayerPosition();
2020-08-01 23:28:24 +00:00
}
}
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);
}
2020-08-02 00:37:57 +00:00
if (entity instanceof ServerPlayerEntity) {
2020-08-20 18:53:53 +00:00
((ServerPlayerEntity) entity).playSound(SoundEvents.BLOCK_PORTAL_TRAVEL, SoundCategory.PLAYERS, 0.25f, world.random.nextFloat() * 0.4f + 0.8f);
2020-08-02 00:37:57 +00:00
}
2020-08-01 23:28:24 +00:00
}
2020-08-02 14:40:08 +00:00
private static int convertY(int y, int oldHeight, int newHeight) {
2020-08-20 18:53:53 +00:00
int newY = (int) (((float) newHeight / (float) oldHeight) * (float) y);
2020-08-19 23:57:38 +00:00
2020-08-20 00:59:16 +00:00
int bottomY = HardcodedConfig.ENERGY_PORTAL_Y_PADDING;
int topY = newHeight - (bottomY + HardcodedConfig.ENERGY_PORTAL_Y_PADDING_EXTRA_TOP);
newY = Math.max(bottomY, Math.min(topY, newY));
2020-08-02 03:15:12 +00:00
2020-08-19 23:57:38 +00:00
return newY;
2020-08-02 03:15:12 +00:00
}
2020-08-01 23:28:24 +00:00
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;
2020-08-02 14:40:08 +00:00
int y = convertY(center.getY(), world.getDimensionHeight(), to.getDimensionHeight());
2020-08-01 23:28:24 +00:00
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);
}
}
}
}
2020-08-02 00:37:57 +00:00
offset = new Vec3d(offset.getX(), Math.max(0, offset.getY()), offset.getZ());
2020-08-01 23:28:24 +00:00
Vec3d target = Vec3d.ofBottomCenter(targetBlock).add(offset);
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));
}
}