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

Версия Minecraft
1.12.2
5,018
47
783
Здравствуйте еще раз. У меня вопрос - мне нужно получить координаты рандомного блока из прогруженных чанков. Каким бы образом можно это провернуть?
Отсчет от игрока не предлагать - не вариант. Точнее, накостылить с сохранением последней позиции игрока в WSD и тому подобной костыльной гадостью, вариант, но во первых это костыль, а во вторых я с WSD не в ладах :)
 
5,018
47
783
А, чет так сложна все!!!):eek:
Короче, чтобы из этого класса мне получить writeToNBT, мне необходимо сделать его статиком. А тогда переменные внутри тоже должны быть статиками. А они ими быть не могут потому что как говорит мне эклипс, ни mc, ни player,ни world не являются статиками...
Java:
    public  class CoordSaveData extends WorldSavedData
    {
        public List<BlockPos> list = new ArrayList<>();

        private final EntityPlayer player = mc.player;
        private final World world = mc.world;
 
5,018
47
783
5,018
47
783
Несколько вопросов по пакету...
Java:
public class WSDCoordToClient implements IMessage { 
    //Какая тут переменная?
    //так что ли?
    public List<BlockPos> listPos;
    public WSDCoordToClient(){}

    public WSDCoordToClient(CoordSaveData data){ 
        
    }
    @Override
    public void fromBytes(ByteBuf buf) { 
        //Что писать тут? нету у байтбуфа ничего связанного с листами или всд(естесно)
    } 
    @Override
    public void toBytes(ByteBuf buf) {   
        //Что писать тут? нету у байтбуфа ничего связанного с листами или всд(естесно)
    }   

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

        @Override
        public IMessage onMessage(WSDCoordToClient message, MessageContext ctx) {
            World world = FMLCommonHandler.instance().getMinecraftServerInstance().getServer().getEntityWorld();
            CoordSaveData data = WSDUtil.get(world, "coord_data", CoordSaveData.class);
            data.writeToNBT(nbt)//откуда тут взять nbt?
        
                return null;   
            }
        }
    }
 
5,018
47
783
Создай лучше пакеты по туториалу ивасика, тебе так легче будет.
Это и есть его пакетная система. Я умею пересылать разные пакеты туда сюда с переменными. Не помню, чтобы в туторе было написано, как пересылать нбт, листы и тому подобные "необычные" вещи. Поэтому и спрашиваю.
 
5,018
47
783
Так... последний штрих. Пакет вроде сделал...
Java:
public class WSDCoordToClient implements IMessage { 

    public NBTTagCompound nbt;
    public WSDCoordToClient(){}

    public WSDCoordToClient(NBTTagCompound nbtLocal){ 
        this.nbt = nbtLocal;
    }
    @Override
    public void fromBytes(ByteBuf buf) { 
        nbt = ByteBufUtils.readTag(buf);
    } 
    @Override
    public void toBytes(ByteBuf buf) {   
        ByteBufUtils.writeTag(buf, nbt);
    }   

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

        @Override
        public IMessage onMessage(WSDCoordToClient message, MessageContext ctx) {
            World world = FMLCommonHandler.instance().getMinecraftServerInstance().getServer().getEntityWorld();
            CoordSaveData data = WSDUtil.get(world, "coord_data", CoordSaveData.class);
            data.writeToNBT(message.nbt);
            return null;   
        }
    }
}
 
5,018
47
783
В эвенте захода в мир... там для отправки на клиент необходим игрок, серверный... Где его взять?
Как обычно?

Java:
        if (event.getEntity() instanceof EntityPlayer) {

            EntityPlayer player = (EntityPlayer) event.getEntity();
 
5,018
47
783
Создай пакет, загрузи в него Nbt тэг(writeToNbt твою ворлдсейвдату), отправь клиенту, на клиенте распакуй: Создай пустую ворлд сейв дату, вызови readFromNbt у всд, из даты вытащи лист.
Если я тебя правильно понял, это вот так?

с нбт непонятка только:unsure:
Java:
    NBTTagCompound nbt = null;
            CoordSaveData data = new CoordSaveData("coord_data");
            data.readFromNBT(nbt);
            int dataX = data.list.get(0);
            int dataY = data.list.get(1);
            int dataZ = data.list.get(2);

Пакет залепил вот так:
Java:
@SubscribeEvent
    public void joinToServer(EntityJoinWorldEvent e)
    {  
        if (e.getEntity() instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) e.getEntity();
            CoordSaveData data = WSDUtil.get(e.getWorld(), "coord_data", CoordSaveData.class);
            NetworkHandler.network.sendTo(new WSDCoordToClient(),(EntityPlayerMP)player);
        }
    }
 
5,018
47
783
2,505
81
397
Хранить все лужи в одном месте и отправлять их все разом на клиент слишком лагодромно. Нужно разбить все по чанкам и синхронить после синхрона чанка. Правда это уже некст левел.
 

Icosider

Kotliner
Администратор
3,603
99
664
Это и есть его пакетная система.
Ты чего-то путаешь, ты используешь пакетную систему форджа, а не мою(хотя моя тоже форджевскую юзает, но она более удобна)

А buf откуда взять?))
Эх, использовал бы мою систему не было б вопросов, в твоём случае "WSDCoordToClient message"
 
5,018
47
783
Итак
Малявой шлю привет от пасанов, шо срок отматали.
В общем, я тут вайта помучал и в итоге из моих луж родилось вот такое, но, нбт своего не выполняет, назначения. Лужи каждый раз при смене координат меняются. Не надо мне советовать переделать все с нуля, ведь уже почти все работает
Итак:
Когда игрок заходит в мир, начинается срабатывание эвента, который отсылает пакеты нбт с сгенерированными лужами на сервере на клиент.
Java:
    @SubscribeEvent
    public void worldTick(PlayerTickEvent e) {
        if(!e.player.world.isRemote) {
            CoordSaveData data = WSDUtil.get(e.player.world, "coord_data", CoordSaveData.class);
            BlockPos pos = e.player.getPosition();
            if(data.list.contains(pos)) {
                return;
            }
            data.list.add(pos);
            NetworkHandler.network.sendTo(new WSDCoordToClient(data.writeToNBT(new NBTTagCompound())), (EntityPlayerMP)e.player);
       
        }
    }
Вот так выглядит пакет, к слову:

Java:
public class WSDCoordToClient implements IMessage { 
   
    public static HashSet<BlockPos> staticList = new HashSet<>();
   
    public NBTTagCompound nbt;
    public WSDCoordToClient(){}

    public WSDCoordToClient(NBTTagCompound nbtLocal){ 
        this.nbt = nbtLocal;
    }
    @Override
    public void fromBytes(ByteBuf buf) { 
        nbt = ByteBufUtils.readTag(buf);
    } 
    @Override
    public void toBytes(ByteBuf buf) {  
        ByteBufUtils.writeTag(buf, nbt);
    }  

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

        @Override
        public IMessage onMessage(WSDCoordToClient message, MessageContext ctx) {
           
            CoordSaveData data = new CoordSaveData("coord_data");
            data.readFromNBT(message.nbt);

            staticList = data.list;
           
            return null;   
        }
   
    }
   
}
Далее в отдельном классе extends WSD у меня идет сохранение
Java:
public class CoordSaveData extends WorldSavedData
{
    Minecraft mc = Minecraft.getMinecraft();
    public HashSet<BlockPos> list = new HashSet<>();

    private BlockPos getCoords() {
        EntityPlayer player = mc.player;
        if(player == null) return new BlockPos(0,0,0);{

            World world = mc.world;
           
                BlockPos playerpos = player.getPosition();
                ChunkProviderClient cp = (ChunkProviderClient) world.getChunkProvider();
                List<Chunk> chunks = Lists.newArrayList(cp.chunkMapping.values());
                Chunk chunk = chunks.get(RandomUtils.nextInt(0, chunks.size()));
                if(chunk == null)return new BlockPos(0,0,0);
                int x = chunk.x << 4;
                int z = chunk.z << 4;
                BlockPos pos = new BlockPos(x+ world.rand.nextInt(16), 3, z + world.rand.nextInt(16));

                return pos;
           
        }

    }


    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, getCoords().getX());
            nbt.setInteger("posY_" + i, getCoords().getY());
            nbt.setInteger("posZ_" + i, getCoords().getZ());
        }
        return nbt;
    }
}
И далее рисуется текстура

Java:
    public BlockPos getRandomCoordFromChunk(World world) {

        ChunkProviderClient cp = (ChunkProviderClient) world.getChunkProvider();
        List<Chunk> chunks = Lists.newArrayList(cp.chunkMapping.values());
        Chunk chunk = chunks.get(RandomUtils.nextInt(0, chunks.size()));
        int x = chunk.x * 16 + RandomUtils.nextInt(0, 16);
        int z = chunk.z * 16 + RandomUtils.nextInt(0, 16);
        BlockPos pos = new BlockPos(x, 0, z);

        return pos;

    }

    @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 && !mc.isGamePaused()) {
            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();

            int dataX, dataY, dataZ;
            for(BlockPos pos :  WSDCoordToClient.staticList){
                dataX = pos.getX();
                dataY = pos.getY();
                dataZ = pos.getZ();
                drawPuddleTexture(player, mc.getRenderPartialTicks(), dataX, dataY, dataZ, 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();
        }
    }
В общем, все работает как надо. Вопрос стоит так: как зафиксировать положение игрока на ближайшие, скажем 1000 тиков. Вот один раз они получились, сгенерили лужи, сохранили коры и лежали 1000 тиков?:(Плеазе, третий день идет...
UP еще одна бяка обнаружилась. При прогрузке чанка происходит краш с нуллом...

Java:
java.lang.NullPointerException: null
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$MapIterator.nextEntry(Long2ObjectOpenHashMap.java:636) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$ValueIterator.next(Long2ObjectOpenHashMap.java:876) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:324) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:344) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.AbstractObjectCollection.toArray(AbstractObjectCollection.java:100) ~[fastutil-7.1.0.jar:?]
    at java.util.ArrayList.<init>(ArrayList.java:178) ~[?:1.8.0_151]
    at com.google.common.collect.Lists.newArrayList(Lists.java:149) ~[guava-21.0.jar:?]
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.getCoords(CoordSaveData.java:32) ~[CoordSaveData.class:?]
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.writeToNBT(CoordSaveData.java:75) ~[CoordSaveData.class:?]
    at ru.legendgamer.Realism.Events.GameEvents.RenderEvents.JoinServerEvent.worldTick(JoinServerEvent.java:28) ~[JoinServerEvent.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_25_JoinServerEvent_worldTick_PlayerTickEvent.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) [EventBus.class:?]
    at net.minecraftforge.fml.common.FMLCommonHandler.onPlayerPreTick(FMLCommonHandler.java:364) [FMLCommonHandler.class:?]
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:228) [EntityPlayer.class:?]
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:423) [EntityPlayerMP.class:?]
    at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:185) [NetHandlerPlayServer.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:212) [NetworkDispatcher$1.class:?]
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307) [NetworkManager.class:?]
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197) [NetworkSystem.class:?]
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:863) [MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741) [MinecraftServer.class:?]
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) [IntegratedServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590) [MinecraftServer.class:?]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]
[01:39:18] [Server thread/ERROR] [FML]: Index: 2 Listeners:
[01:39:18] [Server thread/ERROR] [FML]: 0: NORMAL
[01:39:18] [Server thread/ERROR] [FML]: 1: ASM: ru.legendgamer.Realism.Events.SystemWeight.EventWeight@47b530e0 weightm(Lnet/minecraftforge/fml/common/gameevent/TickEvent$PlayerTickEvent;)V
[01:39:18] [Server thread/ERROR] [FML]: 2: ASM: ru.legendgamer.Realism.Events.GameEvents.RenderEvents.JoinServerEvent@1baab1b1 worldTick(Lnet/minecraftforge/fml/common/gameevent/TickEvent$PlayerTickEvent;)V
[01:39:18] [Server thread/ERROR] [FML]: 3: ASM: ru.legendgamer.Realism.Events.GameEvents.IsSleepingNightEvent@2e259c54 sleep(Lnet/minecraftforge/fml/common/gameevent/TickEvent$PlayerTickEvent;)V
[01:39:18] [Server thread/ERROR]: Encountered an unexpected exception
net.minecraft.util.ReportedException: Ticking player
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:212) ~[NetworkSystem.class:?]
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:863) ~[MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741) ~[MinecraftServer.class:?]
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) ~[IntegratedServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590) [MinecraftServer.class:?]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]
Caused by: java.lang.NullPointerException
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$MapIterator.nextEntry(Long2ObjectOpenHashMap.java:636) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$ValueIterator.next(Long2ObjectOpenHashMap.java:876) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:324) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:344) ~[fastutil-7.1.0.jar:?]
    at it.unimi.dsi.fastutil.objects.AbstractObjectCollection.toArray(AbstractObjectCollection.java:100) ~[fastutil-7.1.0.jar:?]
    at java.util.ArrayList.<init>(ArrayList.java:178) ~[?:1.8.0_151]
    at com.google.common.collect.Lists.newArrayList(Lists.java:149) ~[guava-21.0.jar:?]
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.getCoords(CoordSaveData.java:32) ~[CoordSaveData.class:?]
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.writeToNBT(CoordSaveData.java:75) ~[CoordSaveData.class:?]
    at ru.legendgamer.Realism.Events.GameEvents.RenderEvents.JoinServerEvent.worldTick(JoinServerEvent.java:28) ~[JoinServerEvent.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_25_JoinServerEvent_worldTick_PlayerTickEvent.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) ~[EventBus.class:?]
    at net.minecraftforge.fml.common.FMLCommonHandler.onPlayerPreTick(FMLCommonHandler.java:364) ~[FMLCommonHandler.class:?]
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:228) ~[EntityPlayer.class:?]
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:423) ~[EntityPlayerMP.class:?]
    at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:185) ~[NetHandlerPlayServer.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:212) ~[NetworkDispatcher$1.class:?]
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307) ~[NetworkManager.class:?]
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197) ~[NetworkSystem.class:?]
    ... 5 more
[01:39:18] [Server thread/ERROR]: This crash report has been saved to: C:\Users\Maxims\Desktop\RealismCraft Redux\run\.\crash-reports\crash-2018-07-14_01.39.18-server.txt
[01:39:18] [Server thread/INFO]: Stopping server
[01:39:18] [Server thread/INFO]: Saving players
[01:39:18] [Server thread/INFO]: Saving worlds
[01:39:18] [Server thread/INFO]: Saving chunks for level 'Новый мир'/overworld
[01:39:18] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// Shall we play a game?

Time: 7/14/18 1:39 AM
Description: Ticking player

java.lang.NullPointerException: Ticking player
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$MapIterator.nextEntry(Long2ObjectOpenHashMap.java:636)
    at it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap$ValueIterator.next(Long2ObjectOpenHashMap.java:876)
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:324)
    at it.unimi.dsi.fastutil.objects.ObjectIterators.unwrap(ObjectIterators.java:344)
    at it.unimi.dsi.fastutil.objects.AbstractObjectCollection.toArray(AbstractObjectCollection.java:100)
    at java.util.ArrayList.<init>(ArrayList.java:178)
    at com.google.common.collect.Lists.newArrayList(Lists.java:149)
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.getCoords(CoordSaveData.java:32)
    at ru.legendgamer.Realism.RealismCore.CoordSaveData.writeToNBT(CoordSaveData.java:75)
    at ru.legendgamer.Realism.Events.GameEvents.RenderEvents.JoinServerEvent.worldTick(JoinServerEvent.java:28)
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_25_JoinServerEvent_worldTick_PlayerTickEvent.invoke(.dynamic)
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179)
    at net.minecraftforge.fml.common.FMLCommonHandler.onPlayerPreTick(FMLCommonHandler.java:364)
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:228)
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:423)
    at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:185)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:212)
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197)
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:863)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590)
    at java.lang.Thread.run(Thread.java:748)
 
Последнее редактирование:
опрос стоит так: как зафиксировать положение игрока на ближайшие, скажем 1000 тиков. Вот один раз они получились, сгенерили лужи, сохранили коры и лежали 1000 тиков?:(
Создай какую-нибудь статическую переменную int или long, статическую. А эвенте тика сервера прибавляй единичку. Дальше в эвенте игрока добавь проверку что-то типа myintTicker % 1000 == 0. Лужи будут появляться раз в 50 секунд.
 
5,018
47
783
Сверху