Другие измерения

Версия Minecraft
1.12.2
API
Forge

sk9zist :l

Исправился
981
18
157
Как телепортировать игрока в ад в то место, в каком бы он появился, если бы создал портал?
Я пробовал такой код:
if(playerIn.dimensionId == 0) playerIn.changeDimension(-1);
if(playerIn.dimensionId == -1) playerIn.changeDimension(1);
if(playerIn.dimensionId == 1) playerIn.changeDimension(0);

Но открывается Загрузка мира и Майн зависает с сообщением о нехватке памяти в логах. И только при следующем заходе я оказываюсь в аду (в блоках)
 
Краш-лог
[11:57:32] [Server thread/WARN] [minecraft/MinecraftServer]: Can't keep up! Did the system time change, or is the server overloaded? Running 2704ms behind, skipping 54 tick(s)
Краш-лог:
[11:57:32] [Server thread/WARN] [minecraft/MinecraftServer]: Can't keep up! Did the system time change, or is the server overloaded? Running 2704ms behind, skipping 54 tick(s)
Решение
Решил. (Помогла тема Телепортация в измерение )
Вот готовый код, кому будет надо:
FreeTeleporter.java:
import javax.annotation.Nonnull;

import net.minecraft.block.state.pattern.BlockPattern;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Teleporter;
import net.minecraft.world.WorldServer;

public class FreeTeleporter extends Teleporter
{
    public boolean makePortal(Entity p_85188_1_)
    {...

sk9zist :l

Исправился
981
18
157
Хорошо, покопаюсь в ванильном коде.
Остался только вопрос: как телепортировать в то место в аду, где бы заспавнился портал? Типа, ад намного меньше чем обычный мир - поэтому при создании портала в обычном мире, портал в аду создается на координатах, поделенных на 8
 

sk9zist :l

Исправился
981
18
157
Сделал так:
Java:
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
{
    if(!worldIn.isRemote)
        {
            if(playerIn.dimension == 0)
            {
                FreeTeleporter.teleportToDimension(playerIn, -1, playerIn.posX/8, (double)worldIn.getHeight((int) playerIn.posX/8, (int) playerIn.posZ/8) + 2D + 55D, playerIn.posZ/8);
            } else {
                if(playerIn.dimension == -1)
                {
                    FreeTeleporter.teleportToDimension(playerIn, 1, 15D, 90D, 15D);
                } else {
                    if(playerIn.dimension == 1)
                    {
                        FreeTeleporter.teleportToDimension(playerIn, 0, 0D, 100D, 0D);
                    }
                }
            }
        }
    return new ActionResult<ItemStack>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
}
FreeTeleporter.java:
public class FreeTeleporter extends Teleporter {

    public FreeTeleporter(WorldServer world, double x, double y, double z) {
        super(world);
        this.worldServer = world;
        this.x = x;
        this.y = y;
        this.z = z;
    }

    private final WorldServer worldServer;
    private double x;
    private double y;
    private double z;

    @Override
    public void placeInPortal(@Nonnull Entity entity, float rotationYaw) {
        // The main purpose of this function is to [I]not[/I] create a nether portal
        this.worldServer.getBlockState(new BlockPos((int) this.x, (int) this.y, (int) this.z));

        entity.setPosition(this.x, this.y, this.z);
        entity.motionX = 0.0f;
        entity.motionY = 0.0f;
        entity.motionZ = 0.0f;
    }


    public static void teleportToDimension(EntityPlayer player, int dimension, double x, double y, double z) {
        int oldDimension = player.world.provider.getDimension();
        EntityPlayerMP entityPlayerMP = (EntityPlayerMP) player;
        MinecraftServer server = ((EntityPlayerMP) player).world.getMinecraftServer();
        WorldServer worldServer = server.getWorld(dimension);
        player.addExperienceLevel(0);

        if (worldServer == null || worldServer.getMinecraftServer() == null) {
            throw new IllegalArgumentException("Dimension: " + dimension + " doesn't exist!");
        }

        worldServer.getMinecraftServer().getPlayerList().transferPlayerToDimension(entityPlayerMP, dimension, new FreeTeleporter(worldServer, x, y, z));
        player.setPositionAndUpdate(x, y, z);
        if (oldDimension == 1) {
            player.setPositionAndUpdate(x, y, z);
            worldServer.spawnEntity(player);
            worldServer.updateEntityWithOptionalForce(player, false);
        }
    }

}
Хорошо телепортирует только в эндер мир, так как там карта в основном центрирована по координатам 0 90 0, и можно просто спокойно тепнуться в центр карты. (немного дальше центра, на 15 блоков)
А при телепортации в ад я появляюсь в блоках под порталом (если прокопаться чуть выше - там будет создан портал)
Как сделать, чтобы я не появлялся в блоках, и чтобы (желательно) портал не создавался?
 
Последнее редактирование:

VeniVidiVici

Санта Барбарис
327
15
198
Внимательней изучи класс Teleporter. Там есть и метод, который создаёт портал, кэшируя его позицию, и метод, который перемещает в него игрока. Посмотреть на оба этих метода и сделать как надо тебе - дело пары минут, достаточно внимательно изучать код и вникать в то, что там написано.
 

sk9zist :l

Исправился
981
18
157
Решил. (Помогла тема Телепортация в измерение )
Вот готовый код, кому будет надо:
FreeTeleporter.java:
import javax.annotation.Nonnull;

import net.minecraft.block.state.pattern.BlockPattern;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Teleporter;
import net.minecraft.world.WorldServer;

public class FreeTeleporter extends Teleporter
{
    public boolean makePortal(Entity p_85188_1_)
    {
        return true;
    }
   
    @Override
    public void placeInPortal(@Nonnull Entity p_77185_1_, float rotationYaw)
    {
        int i = MathHelper.floor(p_77185_1_.posX);
        int j = MathHelper.floor(p_77185_1_.posY) - 1;
        int k = MathHelper.floor(p_77185_1_.posZ);
        p_77185_1_.setLocationAndAngles((double)i, (double)j, (double)k, p_77185_1_.rotationYaw, 0.0F);
        p_77185_1_.motionX = p_77185_1_.motionY = p_77185_1_.motionZ = 0.0D;
    }

    public FreeTeleporter(WorldServer world, double x, double y, double z) {
        super(world);
        this.worldServer = world;
        this.x = x;
        this.y = y;
        this.z = z;
    }

    private final WorldServer worldServer;
    private double x;
    private double y;
    private double z;


    public static void teleportToDimension(EntityPlayer player, int dimension, double x, double y, double z) {
        int oldDimension = player.world.provider.getDimension();
        EntityPlayerMP entityPlayerMP = (EntityPlayerMP) player;
        MinecraftServer server = ((EntityPlayerMP) player).world.getMinecraftServer();
        WorldServer worldServer = server.getWorld(dimension);
        player.addExperienceLevel(0);

        if (worldServer == null) {
            throw new IllegalArgumentException("Dimension: " + dimension + " doesn't exist!");
        }
       
        worldServer.getMinecraftServer().getPlayerList().transferPlayerToDimension(entityPlayerMP, dimension, new FreeTeleporter(worldServer, x, y, z));
        player.setPositionAndUpdate(x, y, z);
        if (oldDimension == 1) {
            // For some reason teleporting out of the end does weird things. Compensate for that
            player.setPositionAndUpdate(x, y, z);
            worldServer.spawnEntity(player);
            worldServer.updateEntityWithOptionalForce(player, false);
        }
    }
}
Извиняюсь за такие названия переменных, переделывал для 1.12.2.

А как сделать тему решённой? Убрали шоль
 
Сверху