Уникальное измерение

Версия Minecraft
1.12.2
API
Forge
31
0
Салам фарумчане, сделал собственное измерение и хочу чтобы оно было для каждого игрока уникальным, то есть, у меня есть блок который по нажатию по нему телепортирует в мое измерение, мне нужно сделать так, чтобы, допустим есть игрок 1 и 2, если игрок нажмет на блок портала то для него создается временно новое измерение, и только его туда телепортирует, если игрок 2 нажмет на блок портала то его так же телепортирует в измерение но уже которое создается для него и загружается во второе измерение, это для того, чтобы игроки не встретились и для каждого блока портала было свое временно уникальное измерение, я примерно понимаю как это реализовать, сгенерировать уникальный айди при помощи UUID, и по этому айди сгенерировать изерение, но не до конца понимаю как это исполнить, буду благодарен любой мысли
Метод нажатия в классе блока:
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
        if (!world.isRemote) {
            if (player instanceof EntityPlayerMP) {
                EntityPlayerMP playerMP = (EntityPlayerMP) player;

                MinecraftServer server = world.getMinecraftServer();
                if (server != null) {
                    WorldServer destinationWorld = server.getWorld(2);
                    if (destinationWorld != null) {
                        Teleporter teleporter = new TeleporterCustomDimension(destinationWorld);
                        server.getPlayerList().transferPlayerToDimension(playerMP, 2, teleporter);
                        world.setBlockToAir(pos);
                    }
                }
            }
        }
        return true;
    }
Инит измерения:
public class DimensionInit
{
    public static final DimensionType DANGE = DimensionType.register("Dange", "_dange", 2, DimensionDange.class, false);
   
    public static void registerDimension()
    {
        DimensionManager.registerDimension(2, DANGE);
    }
}
Класс телепортации:
public class TeleporterCustomDimension extends Teleporter {

    private final WorldServer worldServer;

    public TeleporterCustomDimension(WorldServer worldServer) {
        super(worldServer);
        this.worldServer = worldServer;
    }

    @Override
    public void placeInPortal(Entity entity, float rotationYaw) {
        entity.setPositionAndRotation(100, 10, 100, entity.rotationYaw, entity.rotationPitch);
    }

    @Override
    public boolean placeInExistingPortal(Entity entity, float rotationYaw) {
        return false;
    }

    @Override
    public boolean makePortal(Entity entity) {
        return true;
    }
}
Провайдер:
public class DimensionDange extends WorldProvider
{
    public DimensionDange()
    {
        this.biomeProvider = new BiomeProviderSingle(BiomeInit.DANGE);
        this.hasSkyLight = false;
    }
   
    @Override
    public DimensionType getDimensionType()
    {
        return DimensionInit.DANGE;
    }
   
    @Override
    public IChunkGenerator createChunkGenerator()
    {
        return new CustomChunkGenerator(world, true, world.getSeed());
    }
   
    @Override
    public boolean canRespawnHere()
    {
        return false;
    }
   
    @Override
    public boolean isSurfaceWorld()
    {
        return false;
    }
}
 
Последнее редактирование:
428
41
108
public static void registerDimension() { DimensionManager.registerDimension(2, DANGE); }
Вызывай ЭТО перед тем, как игрок будет перемещен в свое измерение, только вместо 2 ставь уникальный ID.

Ну и предварительно сделай проверку, чтобы не вылетело с ошибкой ,,это измерение уже зарегистрировано,,
 
428
41
108
А типа проблем не будет, если будет допустим создано 100 измерений? А если игрок снова захочет посетить какое то уникальное измерение? Будет создаваться новое?
Разве что проблемы с памятью наверное - если измерение долго не используется - его можно выгрузить и ,,разрегистрировать,,

Не уверен только можно ли это сделать легально - или придется миксинами или подобным шаманить
 
31
0
А типа проблем не будет, если будет допустим создано 100 измерений? А если игрок снова захочет посетить какое то уникальное измерение? Будет создаваться новое?
Измерение должно быть временным, и по окончанию времени оно должно удаляться, но думаю с этим проблем не должно быть, мне главное их создавать
 
31
0
Вызывай ЭТО перед тем, как игрок будет перемещен в свое измерение, только вместо 2 ставь уникальный ID.

Ну и предварительно сделай проверку, чтобы не вылетело с ошибкой ,,это измерение уже зарегистрировано,,
Вот пока гулял думал над этим, нужно проверить
 
31
0
Вызывай ЭТО перед тем, как игрок будет перемещен в свое измерение, только вместо 2 ставь уникальный ID.

Ну и предварительно сделай проверку, чтобы не вылетело с ошибкой ,,это измерение уже зарегистрировано,,
Должно получиться что то такого?
Java:
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
        if (!world.isRemote) {
            UUID uniqueID = UUID.randomUUID();
            DimensionType DANGE = DimensionType.register("dange", "_dange", uniqueID, DimensionDange.class, false);
            DimensionManager.registerDimension(uniqueID, DANGE);

            EntityPlayerMP entityPlayerMP = (EntityPlayerMP) player;
            MinecraftServer minecraftServer = world.getMinecraftServer();
            WorldServer worldServer = minecraftServer.getWorld(uniqueID);
            if (worldServer == null) {
                worldServer = ((WorldServer) world).getMinecraftServer().getWorldServer(uniqueID);
            }
            if (worldServer != null) {
                entityPlayerMP.changeDimension(uniqueID, new TeleporterCustomDimension(worldServer));
            }

        }
        return true;
    }
 
116
13
13
Не уверен только можно ли это сделать легально - или придется миксинами или подобным шаманить
Вот кстати да. Если так посмотреть, то dimension зарегистрировать - зарегистрирует, а вот список миров обновляется только при запуске самого сервера.
 
31
0
Звучит логично, как можно обыграть по иному мою идею? вот мне нужно чтобы при нажатии на блок генерировалась постройка, сначала думал сделать чтобы каждая постройка это было отдельное измерение, но видимо это будет не правильно, тогда как мне в одном измерении генерировать постройку для каждого портала? то есть если игрок зашел в портал то для него генерируется постройка? и только для него, если же другой игрок зайдет в портал то для него сгенерируется вторая постройка, которая никак не взаимодействует с постройкой первого игрока, это для того, чтобы игроки между собой не пересекались, и по истечению какого то времени постройка просто удаляется с мира
 
428
41
108
А разве регистрация не фризится после пре-инициализации? Или это ток с 1.13+?
Наверное да?
В ,,Недоделках,, у меня валяется мод, в котором это делается динамически. 1 тип измерения и неограниченное количество миров к нему

Регистрация типов измерений да, только на инити надо делать

Должно получиться что то такого?
1 и тот-же Тип измерения (они у тебя эквивалентные) не нужно регистрировать 10 раз, это глупо
И ID измерения выставлять по UUID игрока с моей точки зрения крайне дико. Лучше в мире или напрямую в данных игрока сделать таблицу сопоставления Игрок - измерение

но видимо это будет не правильно
Не сказал бы - в галактикрафте подобное с космическими станциями (не уверен, требует уточнения)

Звучит логично, как можно обыграть по иному мою идею?
Добавь пару свойств к игроку, в которых указываешь позицию и время создания постройки, чтобы во 2-ой раз телепортировать туда куда нужно и все? Ну и удалить когда нужно.
 
31
0
1 и тот-же Тип измерения (они у тебя эквивалентные) не нужно регистрировать 10 раз, это глупо
И ID измерения выставлять по UUID игрока с моей точки зрения крайне дико. Лучше в мире или напрямую в данных игрока сделать таблицу сопоставления Игрок - измерение
Пожалуйста, eсли не трудно, можно попросить поподробнее рассказать?
 
166
5
14
Не сказал бы - в галактикрафте подобное с космическими станциями
В галактик крафте это вынужденое решение у каждого игрока своё свободное измерение где он может делать что хочет
А тут у нас ограниченая структура из которой скорее всего нельзя выбрался и 2 миллиарда блоков так что по идее бессмысленно
 
Последнее редактирование:
31
0
Можеш в зависимости от того сколько игроков вошло в портал смещать структуру и координаты телепортации игрока допустим на 1000 блоков
Я чего то да сделал, но у меня игрок получает координату в новом измерении как в верхнем мире, то есть если два игрока используют портал в одном месте, то и постройка будет на одинаковых координатах
Метод onBlockActivated в классе портала:
@Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
        if (!worldIn.isRemote) {
            if (!worldIn.isRemote) {
                if (playerIn instanceof EntityPlayerMP) {
                   EntityPlayerMP playerMP = (EntityPlayerMP) playerIn;

                  MinecraftServer server = worldIn.getMinecraftServer();
                    if (server != null) {
                        WorldServer destinationWorld = server.getWorld(2);
                           if (destinationWorld != null) {
                          
                               Teleporter teleporter = new YourTeleport(destinationWorld, 0, 0, 0);
                               server.getPlayerList().transferPlayerToDimension(playerMP, 2, teleporter);

                               worldIn.setBlockToAir(pos);
                               BlockPos newPos = pos.add(1000, 0, 0);
                               MinecraftForge.EVENT_BUS.post(new BuildingGenerationEvent(playerMP, worldIn, newPos));
                          }
                    }
              }
            }
        }
        return true;
    }
Телепорт:
public class YourTeleport extends Teleporter {

     private final WorldServer worldServer;

        public YourTeleport(WorldServer worldServer) {
            super(worldServer);
            this.worldServer = worldServer;
        }

        public void placeInPortal(Entity entity, float rotationYaw, double x, double y, double z) {
            entity.setPositionAndRotation(x, y, z, entity.rotationYaw, entity.rotationPitch);
        }

        @Override
        public boolean placeInExistingPortal(Entity entity, float rotationYaw) {
            return false;
        }

        @Override
        public boolean makePortal(Entity entity) {
            return true;
        }
}
BuildingGenerationEvent:
ublic class BuildingGenerationEvent extends Event {
    private final EntityPlayerMP player;
    private final World world;
    private final BlockPos position;

    public BuildingGenerationEvent(EntityPlayerMP player, World world, BlockPos position) {
        this.player = player;
        this.world = world;
        this.position = position;
    }

    public EntityPlayerMP getPlayer() {
        return player;
    }

    public World getWorld() {
        return world;
    }

    public BlockPos getPosition() {
        return position;
    }
}
 
166
5
14
попробуй этот телепортер попробовать
FreeTeleporter:
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);
        }
    }
}
 
Сверху