Рандомные координаты

Версия Minecraft
1.12.2
5,018
47
783
Здравствуйте еще раз. У меня вопрос - мне нужно получить координаты рандомного блока из прогруженных чанков. Каким бы образом можно это провернуть?
Отсчет от игрока не предлагать - не вариант. Точнее, накостылить с сохранением последней позиции игрока в WSD и тому подобной костыльной гадостью, вариант, но во первых это костыль, а во вторых я с WSD не в ладах :)
 

Icosider

Kotliner
Администратор
3,603
99
664
Обои в итоге сделаны сущностями были:). А так уже все, рисуется.

Java:
    public static void drawPuddleTexture(Entity entityIn, float partialTicks, int x,int y,int z, World world, String texture) {
        double d3 = entityIn.lastTickPosX + (entityIn.posX - entityIn.lastTickPosX) * (double) partialTicks;
        double d4 = entityIn.lastTickPosY + (entityIn.posY - entityIn.lastTickPosY) * (double) partialTicks;
        double d5 = entityIn.lastTickPosZ + (entityIn.posZ - entityIn.lastTickPosZ) * (double) partialTicks;
        Tessellator tessellatorIn = Tessellator.getInstance();
        BufferBuilder bufferBuilderIn = tessellatorIn.getBuffer();
        Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
        bufferBuilderIn.begin(7, DefaultVertexFormats.BLOCK);
        bufferBuilderIn.setTranslation(-d3, -d4, -d5);
        bufferBuilderIn.noColor();
        IBlockState iblockstate = world.getBlockState(new BlockPos(x,y,z));
        TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
        BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();

        blockrendererdispatcher.renderBlockDamage(iblockstate, new BlockPos(x,y,z), texturemap.getAtlasSprite("realism:textatlas/puddle"), world);
        tessellatorIn.draw();

        bufferBuilderIn.setTranslation(0.0D, 0D, 0.0D);

    }
Что это за франкенштейн?))))))

"new BlockPos(x,y,z)" не надо так (((
 
5,018
47
783
Вообщем, сел писать чтобы в всд все это дело сохранялось. Игра виснет, написано СерверСтоппед...
Java:
    private static final String DATA_NAME = Realism.MODID + "_coordData";
    static boolean IS_GLOBAL;
    @SubscribeEvent
    public void handleWorldLoad(WorldEvent.Load event) {
        MapStorage storage = IS_GLOBAL ? event.getWorld().getMapStorage() : event.getWorld().getPerWorldStorage();
        CoordSaveData data = (CoordSaveData) storage.getOrLoadData(CoordSaveData.class, DATA_NAME);
        event.getWorld().getMapStorage().getOrLoadData(CoordSaveData.class, DATA_NAME);

        if (data == null) {
            data = new CoordSaveData(DATA_NAME);
            event.getWorld().getMapStorage().setData(DATA_NAME, data);
        }
        event.getWorld().getMapStorage().setData(DATA_NAME, data);
    }


    public class CoordSaveData extends WorldSavedData
    {
        public List<BlockPos> list = new ArrayList<>();

        private final EntityPlayer player = mc.player;
        private final World world = mc.world;
     
        private BlockPos playerpos = player.getPosition();
        ChunkProviderClient cp = (ChunkProviderClient) world.getChunkProvider();
        Chunk chunk = cp.getLoadedChunk(playerpos.getX() >> 4, playerpos.getZ() >> 4);
        int x = chunk.x << 4;
        int z = chunk.z << 4;

        BlockPos pos = new BlockPos(x, 3, z);


        public CoordSaveData(String name)
        {
            super(name);
        }

        @Override
        public void readFromNBT(NBTTagCompound nbt)
        {
            list.clear();
            final int size = nbt.getInteger("size");

            for (int i = 0; i < size; i++)
            {
                final int posX = nbt.getInteger("posX_" + i);
                final int posY = nbt.getInteger("posY_" + i);
                final int posZ = nbt.getInteger("posZ_" + i);
                list.add(new BlockPos(posX, posY, posZ));
            }
        }

        @Override
        public NBTTagCompound writeToNBT(NBTTagCompound nbt)
        {
            nbt.setInteger("size", list.size());

            for (int i = 0; i < list.size(); i++)
            {
                nbt.setInteger("posX_" + i, pos.getX());
                nbt.setInteger("posY_" + i, pos.getY());
                nbt.setInteger("posZ_" + i, pos.getZ());
            }
            return nbt;
        }
    }

    @SubscribeEvent
    public void render(RenderWorldLastEvent e)
    {
        final Minecraft mc = Minecraft.getMinecraft();
        final World world = mc.world;
        final EntityPlayer player = mc.player;

        if (world != null && player != null)
        {
            GlStateManager.enableBlend();
            GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F);
            GlStateManager.doPolygonOffset(-3.0F, -3.0F);
            GlStateManager.enablePolygonOffset();
            GlStateManager.alphaFunc(516, 0.1F);
            GlStateManager.enableAlpha();
            GlStateManager.pushMatrix();

            playerpos = player.getPosition();
            ChunkProviderClient cp = (ChunkProviderClient) world.getChunkProvider();

            Chunk chunk = cp.getLoadedChunk(playerpos.getX() >> 4, playerpos.getZ() >> 4);
            int x = chunk.x << 4;
            int z = chunk.z << 4;

            BlockPos pos = new BlockPos(x, 3, z);

            drawPuddleTexture(player, mc.getRenderPartialTicks(), pos.getX() + RandomUtils.nextInt(0, 16) , pos.getY(), pos.getZ() + RandomUtils.nextInt(0, 16), world, "realism:textatlas/puddle");
            //    System.out.println("puddle on: " + pos);

            GlStateManager.disableAlpha();
            GlStateManager.doPolygonOffset(0F, 0.0F);
            GlStateManager.disablePolygonOffset();
            GlStateManager.enableAlpha();
            GlStateManager.depthMask(true);
            GlStateManager.popMatrix();
        }
    }
Что это за франкенштейн?))))))
Старый добрый ванильный код рендера текстурки на блоке)
"new BlockPos(x,y,z)" не надо так (((
А как еще коры сделать?:unsure:
 

Icosider

Kotliner
Администратор
3,603
99
664
Старый добрый код рендера текстурки на блоке)
Это извращение.
Java:
private BlockPos playerpos = player.getPosition();
        ChunkProviderClient cp = (ChunkProviderClient) world.getChunkProvider();
        Chunk chunk = cp.getLoadedChunk(playerpos.getX() >> 4, playerpos.getZ() >> 4);
        int x = chunk.x << 4;
        int z = chunk.z << 4;

        BlockPos pos = new BlockPos(x, 3, z);
В метод засунь :m_faceplam:
 
5,018
47
783
ОЙОЙОЙОЙОЙ, ты не правильно(или очень странно) сохраняешь дату в мир.
WorldSavedData для моих жил я делал так:
Получаю значение, в каком-нибудь серверном эвенте
OreGenSavedData data = WorldSavedDataUtil.get(event.getWorld(), "ore_gen_data", OreGenSavedData.class);
Ну и сам код получения:
Java:
public class WorldSavedDataUtil {
    @SuppressWarnings("all")
    public static <T extends WorldSavedData> T get(World world, String name, Class<T> clazzSavedData) {
        T instance = (T) world.getMapStorage().getOrLoadData(clazzSavedData, name);

        if (instance == null) {
            try {
                instance = clazzSavedData.getConstructor(String.class).newInstance(name);
            } catch (Exception e) {
                e.printStackTrace();
            }
            instance.markDirty();
            world.getMapStorage().setData(name, instance);
        }
        return instance;
    }
}
ВСЕ!
Добавляешь теперь все что угодно в свою ворлдсейвдату, ничего сохранять не надо, разве что методы сериализации/десериализации в нбт нормально переопределить. Конструктор со строкой еще не забудь.
 
5,018
47
783
Что? покажи код
Я до твоего сообщения это написал... А зачем мне серверный эвент? Ты что ли, любое значение, которое к тебе в всд попадает, парсишь в стринг и сохраняешь как стринг?
Я чет не понял, как твое работает:unsure:
 
5,018
47
783
5,018
47
783
Я чет не совсем понимаю... можно уточнить, какие данные передает всд ? три int'а?
Java:
public class WSDCoordToClient implements IMessage { 
    public int x; 
    public int y;
    public int z;
    public WSDCoordToClient(){}

    public WSDCoordToClient(int x,int y, int z){ 
        this.x = x;   
        this.y = y;   
        this.z = z;   
    }
    @Override
    public void fromBytes(ByteBuf buf) { 
        x = buf.readInt();   
        y = buf.readInt();   
        z = buf.readInt();   
    } 
    @Override
    public void toBytes(ByteBuf buf) {   
        buf.writeInt(x);
        buf.writeInt(y);
        buf.writeInt(z);
    }   

    public static class Handler implements IMessageHandler<WSDCoordToClient, IMessage> {

        @Override
        public IMessage onMessage(WSDCoordToClient message, MessageContext ctx) {

            //я не въезжаю. что тут получить то надо?
                return null;   
            }
        }
    }
 
5,018
47
783

Icosider

Kotliner
Администратор
3,603
99
664
Я чет не совсем понимаю... можно уточнить, какие данные передает всд ? три int'а?
Java:
public class WSDCoordToClient implements IMessage {
    public int x;
    public int y;
    public int z;
    public WSDCoordToClient(){}

    public WSDCoordToClient(int x,int y, int z){
        this.x = x;  
        this.y = y;  
        this.z = z;  
    }
    @Override
    public void fromBytes(ByteBuf buf) {
        x = buf.readInt();  
        y = buf.readInt();  
        z = buf.readInt();  
    }
    @Override
    public void toBytes(ByteBuf buf) {  
        buf.writeInt(x);
        buf.writeInt(y);
        buf.writeInt(z);
    }  

    public static class Handler implements IMessageHandler<WSDCoordToClient, IMessage> {

        @Override
        public IMessage onMessage(WSDCoordToClient message, MessageContext ctx) {

            //я не въезжаю. что тут получить то надо?
                return null;  
            }
        }
    }
Получаешь WSD который на клиенте и передаешь ему в лист координаты блоков.
 
Создай пакет, загрузи в него Nbt тэг(writeToNbt твою ворлдсейвдату), отправь клиенту, на клиенте распакуй: Создай пустую ворлд сейв дату, вызови readFromNbt у всд, из даты вытащи лист.
 
Сверху