[1.7.10] Щелчок мышью из гуи

435
1
Например у меня есть прозрачный гуи с некоторыми элементами. при открытии этого гуи моя камера перемещается в особую точку откуда видна небольшая часть мира. Теперь вопрос: как получить блок/энтити, если я щелкаю курсором по нему из гуи?
[merge_posts_bbcode]Добавлено: 07.06.2015 21:20:30[/merge_posts_bbcode]

Типа так
a1c3f7ee59ff.png
 
Ты вообще искать умеешь? Кнопочка "Поиск" сверху. Совсем недавно такой вопрос был.
 
Очень хорошее решение от глуми, но только мне нужно еще ловить энтити.

Код:
//не стоит каждый раз создавать новый буфер, это чревато проблемами с производительностью
    private static IntBuffer viewportBuf = BufferUtils.createIntBuffer(16);
    private static FloatBuffer projectionBuf = BufferUtils.createFloatBuffer(16);
    private static FloatBuffer modelviewBuf = BufferUtils.createFloatBuffer(16);

    /**
     * Метод использует текущие матрицу проекции и modelview матрицу, так что вызывать
     * его во время отрисовки ГУИ - не дело. Вызывай в RenderWorldLastEvent, например
     */
    public MovingObjectPosition calcBlockMouseOver(World world){
        GL11.glGetInteger(GL11.GL_VIEWPORT, viewportBuf);
        GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projectionBuf);
        GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelviewBuf);

        float vx = Mouse.getX();
        // я не очень помню, где находится 0 по оси Y: сверху или снизу.
        // если сверху, то vy = mc.displayHeight - Mouse.getY().
        float vy = Mouse.getY();

        // этот буфер не нативный, так что всё ОК
        FloatBuffer resultBuf = FloatBuffer.allocate(3);

        // В той статье предполагается ставить z на -1,
        // но я не уверен, что оно будет правильно работать.
        // Всё-таки миниальная глубина - это 0, а не -1. Решай сам, кому верить 
        Project.gluUnProject(vx, vy, -1, modelviewBuf, projectionBuf, viewportBuf, resultBuf);
        Vec3 p1 = Vec3.createVectorHelper(resultBuf.get(0), resultBuf.get(1), resultBuf.get(2));

        Project.gluUnProject(vx, vy, 1, modelviewBuf, projectionBuf, viewportBuf, resultBuf);
        Vec3 p2 = Vec3.createVectorHelper(resultBuf.get(0), resultBuf.get(1), resultBuf.get(2));
        
        //И всё бы ничего, но p1 и p2 центрированы то ли к камере, то ли к голове персонажа.
        //Склоняюсь ко второму варианту. Поправим это.
        
        p1 = p1.addVector(RenderManager.renderPosX, RenderManager.renderPosY, RenderManager.renderPosZ);
        p2 = p2.addVector(RenderManager.renderPosX, RenderManager.renderPosY, RenderManager.renderPosZ);
        
        return world.clip(p1, p2);
    }
 
На блоках да, только вот это

Код:
return world.clip(p1, p2);
меняем на
Код:
return world.rayTraceBlocks(p1, p2);
[merge_posts_bbcode]Добавлено: 08.06.2015 00:46:40[/merge_posts_bbcode]

Так сделаю пост сюда чтобы не разводить много тем:
В общем нужно разобраться с пакетами.
Слизал основу отсюда: http://www.minecraftforge.net/wiki/Netty_Packet_Handling#PacketPipeline_Class
Сделал свой класс
Код:
package ru.mrcreppo.dotacraft.event;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.entity.player.EntityPlayer;

public class HeroMovePacket extends AbstractPacket {
    
    public HeroMovePacket() {}

    @Override
    public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void handleClientSide(EntityPlayer player) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void handleServerSide(EntityPlayer player) {
        // TODO Auto-generated method stub
        
    }

}

А теперь вопрос - как слать пакеты и как их ловить этим классом
 
Dovakin написал(а):
никак.Тебе даже ByteBuf не даётся
Я просто в 1.7 в пакеты только сейчас полез - в 1.6 все понятнее было.
Тут зарегал все, сделал класс - не знаю как юзать.
[merge_posts_bbcode]Добавлено: 08.06.2015 00:52:35[/merge_posts_bbcode]

Скажем не с клиента нужно отправить некий int iNoob. Как его послать и поработать с ним в моем недоклассе?
 
MrCreppo написал(а):
А теперь вопрос - как слать пакеты и как их ловить этим классом
ЕМНИП, пакеты в 1.7.10 отсылаются несколько иначе. Я использую SimpleNetworkWrapper. А в него уже что хочешь заверни.

[offtop]
[/offtop]
Код:
package ru.mrcreppo.dotacraft.event;
[offtop]
Ты серьезно?
[/offtop]
[merge_posts_bbcode]Добавлено: 07.06.2015 23:56:44[/merge_posts_bbcode]

MrCreppo написал(а):
Dovakin написал(а):
никак.Тебе даже ByteBuf не даётся
Я просто в 1.7 в пакеты только сейчас полез - в 1.6 все понятнее было.
Тут зарегал все, сделал класс - не знаю как юзать.
[merge_posts_bbcode]Добавлено: 08.06.2015 00:52:35[/merge_posts_bbcode]

Скажем не с клиента нужно отправить некий int iNoob. Как его послать и поработать с ним в моем недоклассе?

Глянь у меня CommonProxy и Примеры пакетов.
 
Dovakin написал(а):
Я не использую враппер,ибо есть ещё глаже способ
Так так так, что там за способ? Мне интересно.
 
Код:
public class NetworkManager {

    private final FMLEventChannel channel;
    private final String channelName;
    private final IPacketHandler packetHandler;

    public NetworkManager(String name, IPacketHandler pktHandler) {
        channelName = name;
        channel = NetworkRegistry.INSTANCE.newEventDrivenChannel(channelName);
        channel.register(this);
        packetHandler = pktHandler;
    }

    public static NetworkManager registerPacketHandler(String name, IPacketHandler packetHandler) {
        return new NetworkManager(name, packetHandler);
    }

    @SubscribeEvent
    public void onServerPacket(ServerCustomPacketEvent e) {
        EntityPlayerMP player = ((NetHandlerPlayServer) e.handler).playerEntity;
        ByteBuf buf = e.packet.payload();
        packetHandler.handleServerSide(buf, player.worldObj, player);
    }

    @SubscribeEvent
    public void onClientPacket(ClientCustomPacketEvent event) {
        EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer;
        ByteBuf buf = event.packet.payload();
        packetHandler.handleClientSide(buf, player.worldObj, player);
    }

    public void sendToServer(FMLProxyPacket packet) {
        channel.sendToServer(packet);
    }

    public void sendToClients(FMLProxyPacket packet) {
        channel.sendToAll(packet);
    }

    public void sendToPlayer(FMLProxyPacket packet, EntityPlayerMP player) {
        channel.sendTo(packet, player);
    }

    public void sendToArea(FMLProxyPacket packet, double x, double y, double z, double range, int dim) {
        channel.sendToAllAround(packet, new TargetPoint(dim, x, y, z, range));
    }

    public void sendToDimension(FMLProxyPacket packet, int id) {
        channel.sendToDimension(packet, id);
    }

    public FMLProxyPacket createPacket(Object... data) {
        return createPacket(Unpooled.buffer(32), data);
    }

    public FMLProxyPacket createPacket(ByteBuf buf, Object... data) {
        for (Object obj : data) {
            if (obj instanceof Byte) {
                buf.writeByte((Byte) obj);
            }
            if (obj instanceof Short) {
                buf.writeShort((Short) obj);
            }
            if (obj instanceof Integer) {
                buf.writeInt((Integer) obj);
            }
            if (obj instanceof Float) {
                buf.writeFloat((Float) obj);
            }
            if (obj instanceof Double) {
                buf.writeDouble((Double) obj);
            }
            if (obj instanceof Long) {
                buf.writeLong((Long) obj);
            }
            if (obj instanceof Character) {
                buf.writeChar((Character) obj);
            }
            if (obj instanceof String) {
                ByteBufUtils.writeUTF8String(buf, (String) obj);
            }
            if (obj instanceof ItemStack) {
                ByteBufUtils.writeItemStack(buf, (ItemStack) obj);
            }
            if (obj instanceof NBTTagCompound) {
                ByteBufUtils.writeTag(buf, (NBTTagCompound) obj);
            }
        }
        return new FMLProxyPacket(buf, channelName);
    }
}

И реализуем интерфейс,а там jopa 2 метода.Всё делается в 2 эвентах
 
Dovakin написал(а):
Решил почитать об этом способе. У первого гайда в списке от гугла красными буквами надпись : cpw реккомендует использовать SimpleNetworkWrapper. Кстати вот классный гайд.
 
Agravaine написал(а):
Не знаю, мне например не нравится делать на каждый пакет новый класс.
А я в 1.6 на каждый пакет по классу делаю xD
ИМХО форджевская система в 1.6 всё-таки неудобная. В 1.7 как-то элегантнее, что ли.
 
Назад
Сверху