GuiHandler

Версия Minecraft
1.7.10
608
5
15
В GuiHandler есть 2 метода. getServerGuiElement, getClientGuiElement

Я так понял, что это сделано для синхронизации?
Сделал я gui, container, всё как обычно. Но при перемещении/закрытии открытии происходит какая-то фигня. То в слоты для брони залетят предметы, то продаблятся, и прочие аномалии.

Или надо как-то вручную синхронизировать?
Код:
package ua.svk.WipeChest.gui;

import cpw.mods.fml.common.network.IGuiHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import ua.svk.WipeChest.base.MainMod;

public class GuiHandler implements IGuiHandler
{
 public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z)
 {
 ItemStack stack = player.getCurrentEquippedItem();

 if(id == 0 && stack != null && stack.hasTagCompound())
 {
 System.out.println("+");
 return new ContainerWipeChest(player.inventory, new InventoryWipeChest());
 }
 else
 {
 return null;
 }
 }

 public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z)
 {
 ItemStack stack = player.getCurrentEquippedItem();

 if(id == 0 && stack != null && stack.hasTagCompound())
 {
 System.out.println("+");
 return new GuiWipeChest(player.inventory, new InventoryWipeChest());
 }
 else
 {
 return null;
 }
 }
}
Код:
package ua.svk.WipeChest.gui;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;

public class ContainerWipeChest extends Container
{
 public ContainerWipeChest(InventoryPlayer playerInventory, InventoryWipeChest inv)
 { 
 for(int i = 0; i < 9; i++)
 {
 this.addSlotToContainer(new Slot(playerInventory, i, 106+i*18, 110+57));
 }
 
 for(int i = 0;i < 3; i++)
 {
 for(int j = 0; j < 9;j++)
 {
 this.addSlotToContainer(new Slot(playerInventory, 9+j+i*9, 106+18*j, 110+i*18));
 }
 }
 }

 @Override
 public boolean canInteractWith(EntityPlayer player)
 {
 return true;
 }
}
Код:
package ua.svk.WipeChest.gui;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import ua.svk.WipeChest.RenderHelper;
import ua.svk.WipeChest.base.ModInfo;

public class GuiWipeChest extends GuiContainer
{
 ResourceLocation texture = new ResourceLocation(ModInfo.MODID, "textures/gui/bg.png");
 
 public GuiWipeChest(InventoryPlayer playerInventory, InventoryWipeChest inv)
 {
 super(new ContainerWipeChest(playerInventory, inv));
 }

 @Override
 protected void drawGuiContainerBackgroundLayer(float f, int x, int y)
 { 
 GL11.glTranslatef(0, 0.2F, 0);
 RenderHelper.drawTextureRect(texture, this.guiLeft, this.guiTop, this.xSize, this.ySize);
 GL11.glTranslatef(0, -0.2F, 0);
 }
 
 @Override
 public void initGui()
 {
 super.xSize = 374;
 super.ySize = 203;
 super.guiLeft = (this.width - this.xSize) / 2;
 super.guiTop = (this.height - this.ySize) / 2;
 }
}
 
216
6
19
svk2140 написал(а):
Что это значит? :|

Это значит, что ты создаешь 2 инвентаря каждый раз, для сервера и для клиента вот игра и сходит с ума. Ты сделай инвентарь переменной, переменную расположи в контейнере и получай его оттуда в гуи
 
3,005
192
592
svk2140 написал(а):
Код:
return new ContainerWipeChest(player.inventory, new InventoryWipeChest());
 return new GuiWipeChest(player.inventory, new InventoryWipeChest());

Ты всегда делаешь новы "[font=Monaco, Consolas, Courier, monospace]new InventoryWipeChest()[/font]", а так не нужно делать.
 
2,505
81
397
Onneros написал(а):
Это значит, что ты создаешь 2 инвентаря каждый раз, для сервера и для клиента вот игра и сходит с ума.
А ничего, что инвентарь с разных сторон сам по себе итак разный?


Судя по названию класса (Chest), должен быть тайл. Оттуда и бери инвентарь.


svk2140 написал(а):
Я так понял, что это сделано для синхронизации?
Это сделано для того, чтобы на серверной стороне открыть контейнер, а на клиентской гуи-контейнер или скрин. Это прокси. За синхронизацию отвечает контейнер. Каждый тик (да, каждый тик) и при изменении ищутся изменения и отправляются клиенту. Ловятся контейнером, который создал гуи-контейнер.
 
7,099
324
1,510
Dahaka написал(а):
Каждый тик (да, каждый тик) и при изменении ищутся изменения и отправляются клиенту.
Значит, вот такая оптимизация вовсе не оптимизация, а лишняя хрень?

Код:
//Это Scala, но ты поймешь, наверное
abstract class BasicTile(invSize:Int) extends TileEntity with ITickable{
  def onInventoryChanged()//Метод, определяется в подклассах

  private var changed=false//Переменная-маркер

 val inv=new InventoryBasic(getClass.getName,true,invSize)
 inv.addInventoryChangeListener((invBasic: IInventory) => {//Помечаем, что изменилось
   changed=true
 })

 override def update(): Unit = {
   if(changed){//Применяем пометку
     onInventoryChanged()
     changed=false
   }
 }
}

Или каждый тик оно чекает только пока контейнер открыт?
 
2,505
81
397
Да, пока контейнер открыт. Из апдейт тика игрока. Лично просто метод detectAndSendChanges переопределяю на пустой. Таким образом ничего не обновляется. А затем синхроню вручную при изменении контейнера.
 
608
5
15
1 - мне не нужен тайл. Всё серверные InventoryWipeChest хранятся в листе. Но для теста, я просто создаю новый.
2 - так и не понял, что мне надо сделать. Оно же всё должно автоматом синхронизировать? Что-бы клиентский конейнер соответсвовал серверному?

Почему тогда происходит всякая хрень, с инвентарём ИГРОКА? Помогите :(
 
1,057
50
234
Код:
public class GSGuiHandler implements IGuiHandler
{
	
    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
        EntityPlayerMP playerBase = PlayerUtil.getPlayerBaseServerFromPlayer(player, false);
        GuiContainerGC inv;
        InventoryPlayer inv1 = player.inventory;
        GCPlayerStats stats = GCPlayerStats.get(playerBase);

        if (playerBase == null)
        {
            player.addChatMessage(new ChatComponentText("Galacticraft player instance null server-side. This is a bug."));
            return null;
        }
        
        TileEntity tile = world.getTileEntity(x, y, z);

        if (tile != null)
        {
        	
            if (tile instanceof TileEntityAssemblyMachine)
            {
                return new ContainerAssemblyMachine(player.inventory, (TileEntityAssemblyMachine) tile);
            }
            
            if (tile instanceof TileEntityGeothermalGenerator)
            {
                return new ContainerGeothermalGenerator(player.inventory, (TileEntityGeothermalGenerator) tile);
            }
            
            if (tile instanceof TileEntityFuelGenerator)
            {
                return new ContainerFuelGenerator(player.inventory, (TileEntityFuelGenerator) tile);
            }
            
            if (tile instanceof TileEntityStorageModule)
            {
                return new ContainerStorageModule(player.inventory, (TileEntityStorageModule) tile);
            }
            
            if (tile instanceof TileEntitySolarWind)
            {
                return new ContainerSolarWind(player.inventory, (TileEntitySolarWind) tile);
            }
            
            if (tile instanceof TileEntityConverterSurface)
            {
                return new ContainerConverterSurface(player.inventory, (TileEntityConverterSurface) tile);
            }
            
            if (tile instanceof TileEntityOxStorageModule)
            {
                return new ContainerOxStorageModule(player.inventory, (TileEntityOxStorageModule) tile);
            }
                    
            if (tile instanceof TileEntitySolarPanel)
            {
                return new ContainerSolarPanel(player.inventory, (TileEntitySolarPanel) tile);
            }
            
            if (tile instanceof TileEntityGravitationModule)
            {
                return new ContainerGravitationModule(player.inventory, (TileEntityGravitationModule) tile);
            }
            
            if (tile instanceof TileEntityWindTurbine)
            	return new ContainerWindTurbine(player.inventory, (TileEntityWindTurbine) tile);
        }
        
                   

        return null;
    }

    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
        if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT)
        {
            return this.getClientGuiElement(ID, player, world, new Vector3(x, y, z));
        }
        
        return null;
    }

    @SideOnly(Side.CLIENT)
    private Object getClientGuiElement(int ID, EntityPlayer player, World world, Vector3 position)
    {
        EntityClientPlayerMP playerClient = PlayerUtil.getPlayerBaseClientFromPlayer(player, false);

        TileEntity tile = world.getTileEntity(position.intX(), position.intY(), position.intZ());
        
        if (tile != null)
        {
        	
            if (tile instanceof TileEntityAssemblyMachine)
            {
                return new GuiAssemblyMachine(player.inventory, (TileEntityAssemblyMachine) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityGeothermalGenerator)
            {
                return new GuiGeothermalGenerator(player.inventory, (TileEntityGeothermalGenerator) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityFuelGenerator)
            {
                return new GuiFuelGenerator(player.inventory, (TileEntityFuelGenerator) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityStorageModule)
            {
                return new GuiStorageModule(player.inventory, (TileEntityStorageModule) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntitySolarWind)
            {
                return new GuiSolarWind(player.inventory, (TileEntitySolarWind) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityConverterSurface)
            {
                return new GuiConverterSurface(player.inventory, (TileEntityConverterSurface) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityOxStorageModule)
            {
                return new GuiOxStorageModule(player.inventory, (TileEntityOxStorageModule) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntitySolarPanel)
            {
                return new GuiSolarPanel(player.inventory, (TileEntitySolarPanel) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            if (tile instanceof TileEntityGravitationModule)
            {
                return new GuiGravitationModule(player.inventory, (TileEntityGravitationModule) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
            }
            
            if (tile instanceof TileEntityWindTurbine)
            	return new GuiWindTurbine(player.inventory, (TileEntityWindTurbine) world.getTileEntity(position.intX(), position.intY(), position.intZ()));
                           
            
        }
        
         return null;
    }
}
 
2,505
81
397
svk2140 написал(а):
Да, от сервера вызываю. И что это за фигня такая?...

Решил посмотреть твой код. Ты же вайп инвентарь вообще не используешь. Только инвентарь игрока. Скорее всего ты просто неправильные слоты заполняешь. Посмотри, как в сундуке или печке.


Ivasik написал(а):
Я бы всё под switch запихнул...
Ну если бы switch поддерживал instanceof, то да.. Но это не так, поэтому ты бы не запихнул ;)


BlesseNtumble написал(а):
Специально создать вектор, чтобы сразу же развернуть его вот в такое position.intX(), position.intY(), position.intZ()? Серьезно?
 
3,005
192
592
BlesseNtumble написал(а):
Код:
           if (tile instanceof TileEntityAssemblyMachine)
            if (tile instanceof TileEntityGeothermalGenerator)
            if (tile instanceof TileEntityFuelGenerator)
            if (tile instanceof TileEntityStorageModule)
            if (tile instanceof TileEntitySolarWind)
            if (tile instanceof TileEntityConverterSurface)
            if (tile instanceof TileEntityOxStorageModule)
            if (tile instanceof TileEntitySolarPanel)
            if (tile instanceof TileEntityGravitationModule)
            if (tile instanceof TileEntityWindTurbine)

А не проще юзать переменные из ID ? 
И после просто switch с return'ом.
И да, лучше else if, ибо оно всегда чекает все варианты.


@svk2140 Попробуй так добавлять слоты:
for (int i = 0; i < 3; i++)
for (int j = 0; j < 9; j++)
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 106 + j * 18, 110 + i * 18));

for (int i = 0; i < 9; i++)
addSlotToContainer(new Slot(inventoryPlayer, i, 106 + i * 18, 110+57));
 
Сверху