[1.7.10] GUI меню от блок

Версия Minecraft
1.7.10
API
Forge
делал GUI по этой теме тык но тут проблемка не могу открыть её по блоку

TestBlock:
package spokers.block;

import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import spokers.Entity.TileEntityTest;
import spokers.Spokers;
import spokers.block.gui.GuiHandlerP;
import spokers.block.gui.GuiP;

public class Tst extends Block implements ITileEntityProvider {

    public Tst() {
        super(Material.circuits);
        setCreativeTab(Spokers.spokerstab);
        setHardness(0.25F);
        setStepSound(soundTypeMetal);
        setBlockTextureName("iron_block");
        setBlockName(Spokers.MODID + ".block_techne1");
    }

    @Override
    public TileEntity createNewTileEntity(World world, int metadata) {
        return new TileEntityTest();
    }

    public int getRenderType() {
        return -1;
    }

    public boolean isOpaqueCube() {
        return false;
    }

    public boolean renderAsNormalBlock() {
        return false;
    }

    @Override
    public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float clickX,
                                    float clickY, float clickZ) {
        Block block = world.getBlock(x, y, z);
        TileEntity entity = world.getTileEntity(x, y, z);
        // Открыть GUI только, если игрок, блок и TileEntity не равны нулю, а также TileEntity является инстанцией нужного.
        if (block != null && entity instanceof TileEntityTest && player != null) {
            // Открыть GUI, если игрок не сидит.
            if (!player.isSneaking()) {
                // Открыть у игрока GUI из мода (первый аргумент) под id (второй аргумент).
                player.openGui(Spokers.instance, 0, world, x, y, z);
                return true;
            }
        }
        return false;
    }
}

ContainerP:
package spokers.block.Container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import spokers.block.Entity.TileEntityP;

public class ContainerP extends Container {
    private TileEntityP tile;

    /**
     * В аргументы указывается инвентарь игрока и TileEntity, который мы открыли
     */
    public ContainerP(InventoryPlayer player, TileEntityP testTile) {
    /* Назначаем локальный TileEntity на тот, откуда открывается контейнер. Нужно для методов,
    что требуют TileEntity. */
        tile = testTile;
        //Переменная, отвечающая за id слота, да, они не должны повторятся.
        int i = 0;
    /* Метод, отвечающий за добавление слота, для конструктора обычного слота используется:
    IInventory (Тут - инвентарь TileEntity), id слота (будет использовать getStackInSlot, или как его там),
    два целых числа, обозначающие местонахождение слота. */
        addSlotToContainer(new Slot(testTile, i++, 8, 38));
        //Второй слот инвентаря
        addSlotToContainer(new Slot(testTile, i++, 44, 21));
    /* Два цикла, отвечающие за добавление инвентаря игрока (второй - его хотбар) в привычные места
    интерфейса (и контейнера). Да, just copy paste. */
        for (i = 0; i < 3; ++i) {
            for (int j = 0; j < 9; ++j) {
                this.addSlotToContainer(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }
        for (i = 0; i < 9; ++i) {
            this.addSlotToContainer(new Slot(player, i, 8 + i * 18, 142));
        }
    }


    /**
     * Метод, который выполняется до открытия контейнера и GUI, обычно используется для проверки расстояния
     * между игроком и TileEntity (и отмены открытия, если оно слишком большое).
     */
    @Override
    public boolean canInteractWith(EntityPlayer player) {
        return tile.isUseableByPlayer(player);
    }
}

GuiP:
package spokers.block.gui;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import spokers.Spokers;
import spokers.block.Container.ContainerP;
import spokers.block.Entity.TileEntityP;

public class GuiP extends GuiContainer {

    private static final ResourceLocation textures = new ResourceLocation(
            Spokers.MODID, "textures/gui/container/GUI.png");

    private TileEntityP tile;

    public GuiP(InventoryPlayer player, TileEntityP tileTest) {
        // Сюда указать объект контейнера.
        super(new ContainerP(player, tileTest));
        // Сохраняем TileEntity в объекте GUI для использования другими методами.
        tile = tileTest;
    }

    /**
     * Метод для отрисовки текстов и etc.
     */
    @Override
    protected void drawGuiContainerForegroundLayer(int x, int y) {
        // Отрисовать название инвентаря игрока, где оно обычно находится.
        fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, ySize - 96 + 2,
                4210752);
        // Отрисовать название GUI (TileEntity), учитывая его переименование и локализацию.
        String s = tile.hasCustomInventoryName() ? tile.getInventoryName()
                : I18n.format(tile.getInventoryName(), new Object[0]);
        fontRendererObj.drawString(s, 6, 6, 4210752);
    }

    /**
     * Метод отрисовки задника GUI (фон, etc).
     */
    @Override
    public void drawGuiContainerBackgroundLayer(float size, int x, int y) {
        // Окрасить все в белый цвет и в полную непрозрачность, не уверен в нужности.
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        // Привязать текстуру
        mc.getTextureManager().bindTexture(textures);
    }
}
GuiHandlerP:
package spokers.block.gui;

import cpw.mods.fml.common.network.IGuiHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import spokers.block.Container.ContainerP;
import spokers.block.Entity.TileEntityP;

public class GuiHandlerP implements IGuiHandler {
    /**
     * Вызов контейнера при его открытии.
     */
    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        // Получить TileEntity, из которого вызван контейнер.
        TileEntity tile = world.getTileEntity(x, y, z);
    /* Проверяем id контейнера на ноль (первый), можно вынести id контейнеров в константы.
    Также проверяем, что TileEntity является тем, для которого сделан контейнер. */
        if (ID == 0 && tile instanceof TileEntityP)
            return new ContainerP(player.inventory, (TileEntityP) tile);
        // Ничего не возвращаем, сли не один из контейнеров не был вызван.
        return null;
    }

    /**
     * Вызов GUI для контейнера.
     */
    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        // Получить TileEntity, из которого вызван GUI.
        TileEntity tile = world.getTileEntity(x, y, z);
        // Проверить id (оно должно совпадать с id контейнера) и TileEntity на принадлежность к GUI.
        if (ID == 0 && tile instanceof TileEntityP)
            return new GuiP(player.inventory, (TileEntityP) tile);
        return null;
    }
}
TileEntityP:
package spokers.block.Entity;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;

public class TileEntityP extends TileEntity implements IInventory {

    public TileEntityP() {

    }

    @Override
    public int getSizeInventory() {
        return 8;
    }

    @Override
    public ItemStack getStackInSlot(int i) {
        return null;
    }

    @Override
    public ItemStack decrStackSize(int i, int i1) {
        return null;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int i) {
        return null;
    }

    @Override
    public void setInventorySlotContents(int i, ItemStack itemStack) {

    }

    @Override
    public String getInventoryName() {
        return "null";
    }

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer entityPlayer) {
        return false;
    }

    @Override
    public void openInventory() {

    }

    @Override
    public void closeInventory() {

    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemStack) {
        return false;
    }
}
Spokers:
package spokers;


import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import net.minecraft.creativetab.CreativeTabs;
import spokers.CreativeTab.SpokersTab;
import spokers.Recipes.Recipe;
import spokers.block.Blocks;
import spokers.block.gui.GuiHandlerP;
import spokers.items.Items;

@Mod(modid = Spokers.MODID, version = Spokers.VERSION, name = Spokers.NAME)

public class Spokers {
    public static final String MODID = "Spokers";
    public static final String VERSION = "1";
    public static final String NAME = "Spokerss";

    @Mod.Instance(Spokers.MODID) public static Spokers instance;
    @SidedProxy(modId = Spokers.MODID, clientSide = "spokers.ProxyClient", serverSide = "spokers.ProxyCommon")
    public static ProxyCommon proxy;

    public static CreativeTabs spokerstab = new SpokersTab("11");

    @Mod.EventHandler
    public void init(FMLInitializationEvent event)
    {
        proxy.init();
        NetworkRegistry.INSTANCE.registerGuiHandler(Spokers.instance, new GuiHandlerP());
    }

    @Mod.EventHandler
    public void preload(FMLPreInitializationEvent event){
        Recipe.registerRecipes();
    }

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {

        Items.registerItems();
        Blocks.registerBlock();

        proxy.preInit();

    }

}

Возникает вопрос ещё что вставлять сюда
Testblokc (Tst)
player.openGui(Spokers.instance, 0, world, x, y, z);
 

sk9zist :l

Исправился
981
18
157
подогнать размеры this.xSize, this.ySize
Ну у него текстура подобно стандартной, т.е. теже пропорции, так что ему это не нужно.

Хотя делается это вот так (до отрисовки):
Java:
int x = (width - xSize) / 2;
        int y = (height - ySize) / 2;
И потом уже эти x и y указывать в методе drawTextureModalRect
 
390
7
27
В тайл:
Java:
public ItemStack[] inventory = new ItemStack[сколько тебе надо];

В контейнере
Java:
addSlotToContainer(new Slot(твой тайл, id, x, y));
Айди начинай с 0 и не превышай значение стака в тайле
 

sk9zist :l

Исправился
981
18
157
а как мне сделать слоты под всю гуй я так ещё и не понял
Вот твой метод, который отвечает за их добавление:
Java:
public ContainerP(InventoryPlayer player, TileEntityP testTile) {
    /* Назначаем локальный TileEntity на тот, откуда открывается контейнер. Нужно для методов,
    что требуют TileEntity. */
        tile = testTile;
        //Переменная, отвечающая за id слота, да, они не должны повторятся.
        int i = 0;
    /* Метод, отвечающий за добавление слота, для конструктора обычного слота используется:
    IInventory (Тут - инвентарь TileEntity), id слота (будет использовать getStackInSlot, или как его там),
    два целых числа, обозначающие местонахождение слота. */
        addSlotToContainer(new Slot(testTile, i++, 8, 38));
        //Второй слот инвентаря
        addSlotToContainer(new Slot(testTile, i++, 44, 21));
    /* Два цикла, отвечающие за добавление инвентаря игрока (второй - его хотбар) в привычные места
    интерфейса (и контейнера). Да, just copy paste. */
        for (i = 0; i < 3; ++i) {
            for (int j = 0; j < 9; ++j) {
                this.addSlotToContainer(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }
        for (i = 0; i < 9; ++i) {
            this.addSlotToContainer(new Slot(player, i, 8 + i * 18, 142));
        }
    }
Конкретно твои слоты добавляют два этих метода:
Java:
/* Метод, отвечающий за добавление слота, для конструктора обычного слота используется:
    IInventory (Тут - инвентарь TileEntity), id слота (будет использовать getStackInSlot, или как его там),
    два целых числа, обозначающие местонахождение слота. */
        addSlotToContainer(new Slot(testTile, i++, 8, 38));
        //Второй слот инвентаря
        addSlotToContainer(new Slot(testTile, i++, 44, 21));
Так как методы не различаются, то советую тебе свою статью, где до мелочей описывается как добавлять свои слоты (а также создание блока, но он на версию 1.12.2, так что тебе нужны только слоты):

А вообще, судя по GUI, который ты скинул - тебе нужно сделать не обычное хранилище, а блок печки... Так что всё, что ты сейчас сделал нужно будет переделать... Однако я незнаю где найти туториал по созданию печи на версию 1.7.10 (на форуме таких вроде нет, хотя возможно есть темы, где это объясняется)
 

sk9zist :l

Исправился
981
18
157

sk9zist :l

Исправился
981
18
157
туторы по крафтам из своей GUI?
В этом туторе есть класс SimpleRecipes, просто скопируй его и добавь любые свои рецепты. Каким методом - там написано, хотя класс всё равно маленький, можно будет разобраться...
 

sk9zist :l

Исправился
981
18
157
предмет в гуй слот он исчезает, не падает куда-то а просто исчезает
Ты шифтом перемещаешь? Вручную попробуй. И у кого-то вроде была подобная проблема, поищи по форуму
 

sk9zist :l

Исправился
981
18
157
делай markDirty()
А еще проверь метод setInventorySlotContents, правильно ли там все, инет ли случайно аннотации "@SideOnly(Side.CLIENT)"


Вот тема с похожей проблемой:
 

sk9zist :l

Исправился
981
18
157
Отправь заного код всего что связано с твоим блоком, тайл энтити (кроме регистрации).
 
ContainerP:
package spokers.block.Container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import spokers.block.Entity.TileEntityP;
import spokers.items.IronCoal;

public class ContainerP extends Container {
    private TileEntityP tile;
    int i = 0;

    public ContainerP(InventoryPlayer player, TileEntityP testTile) {
        tile = testTile;
        //первая линия
        addSlotToContainer(new Slot(testTile, 1, 8, 9));
        addSlotToContainer(new Slot(testTile, 2, 26, 9));
        addSlotToContainer(new Slot(testTile, 3, 44, 9));
        //Вторая линия
        addSlotToContainer(new Slot(testTile, 4, 8, 27));
        addSlotToContainer(new Slot(testTile, 5, 26, 27));
        addSlotToContainer(new Slot(testTile, 6, 44, 27));
        //третья линия
        addSlotToContainer(new Slot(testTile, 7, 8, 45));
        addSlotToContainer(new Slot(testTile, 8, 26, 45));
        addSlotToContainer(new Slot(testTile, 9, 44, 45));
        //четвёртая линия
        addSlotToContainer(new Slot(testTile, 10, 8, 63));
        addSlotToContainer(new Slot(testTile, 11, 26, 63));
        addSlotToContainer(new Slot(testTile, 12, 44, 63));
        //Слот 1 (Шаблон) Слот 2 (Материал) Слот 3 (Шаблон на материале)
        addSlotToContainer(new Slot(testTile, 13, 80, 9));// 1
        addSlotToContainer(new Slot(testTile, 14, 80, 45));// 2
        addSlotToContainer(new Slot(testTile, 15, 128, 27));// 3

        for (i = 0; i < 3; ++i) {
            for (int j = 0; j < 9; ++j) {
                this.addSlotToContainer(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }
        for (i = 0; i < 9; ++i) {
            this.addSlotToContainer(new Slot(player, i, 8 + i * 18, 142));
        }
    }

    @Override
    public ItemStack transferStackInSlot(EntityPlayer player, int slotID) {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(slotID);

        if (slot != null && slot.getHasStack()) {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (slotID < tile.getSizeInventory()) {
                if (!this.mergeItemStack(itemstack1, tile.getSizeInventory() - 9, this.inventorySlots.size(), true))
                    return null;
            } else if (!this.mergeItemStack(itemstack1, 0, tile.getSizeInventory() - 9, false))
                return null;

            if (itemstack1.stackSize == 0)
                slot.putStack(null);
            else
                slot.onSlotChanged();
        }

        return itemstack;
    }

    @Override
    public boolean canInteractWith(EntityPlayer player) {
        return tile.isUseableByPlayer(player);
    }
}
TileEntityP:
package spokers.block.Entity;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryBasic;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;


public class TileEntityP extends TileEntity implements IInventory {

    public InventoryBasic inventory;
    private ItemStack[] stackResult = new ItemStack[1];

   public TileEntityP() {
        inventory = new InventoryBasic("Namer", true, 15);
    }

    @Override
    public void writeToNBT(NBTTagCompound compound)
    {
        super.writeToNBT(compound);
        NBTTagList list = new NBTTagList();

        for(int i = 0; i < inventory.getSizeInventory(); i++)
        {
            if(inventory.getStackInSlot(i) != null)
            {
                NBTTagCompound component = new NBTTagCompound();
                component.setByte("Slot", (byte)i);
                inventory.getStackInSlot(i).writeToNBT(component);
                list.appendTag(component);
            }
        }
        compound.setTag("ItemStaks", list);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);
        NBTTagList ls = compound.getTagList("ItemStaks", 10);
        this.inventory = new InventoryBasic("Namer", false, 15);
        for(int i = 0; i < ls.tagCount(); i++)
        {
            NBTTagCompound tag = ls.getCompoundTagAt(i);
            byte b = tag.getByte("Slot");
            if(b >= 0 && b < inventory.getSizeInventory())
            {
                inventory.setInventorySlotContents(b, ItemStack.loadItemStackFromNBT(tag));
            }
        }
    }

    @Override
    public int getSizeInventory() {
        return 1;
    }

    public ItemStack getStackInSlot(int p_70301_1_)
    {
        return this.stackResult[0];
    }

    @Override
    public ItemStack decrStackSize(int i, int i1) {
        return null;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int i) {
        return null;
    }


    @Override
    public String getInventoryName() {
        return "spokers.press";
    }

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_)
    {
        this.stackResult[0] = p_70299_2_;
    }

    public void onInventoryChanged() {

    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer entityPlayer) {
        return this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false: entityPlayer.getDistanceSq((double)this.xCoord + 0.5D,(double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
    }

    @Override
    public void openInventory() {

    }

    @Override
    public void closeInventory() {

    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemStack) {
        return true;
    }
}
GUIHANDLERP и GUIP я не трогал
 

sk9zist :l

Исправился
981
18
157
@Override public int getSizeInventory() { return 1; }
Зачем тут 1...
1 слот инвентаря - поэтому и ложится во все. Потому что он думает что все слоты это один
И почему у тебя в decrStackSine нулл.. и в других методах
 
И почему у тебя в decrStackSine нулл.. и в других методах
В первый раз делаю GUI и не знаю что ставить в этих методах, вот даже я поставил 15 но как итог всё в 1
UPD: и так я разобрался
UPD2: предметы в гуй не сохраняются после перезахода в мир
 
Последнее редактирование:

sk9zist :l

Исправился
981
18
157
//первая линия addSlotToContainer(new Slot(testTile, 1, 8, 9)); addSlotToContainer(new Slot(testTile, 2, 26, 9)); addSlotToContainer(new Slot(testTile, 3, 44, 9)); //Вторая линия addSlotToContainer(new Slot(testTile, 4, 8, 27)); addSlotToContainer(new Slot(testTile, 5, 26, 27)); addSlotToContainer(new Slot(testTile, 6, 44, 27)); //третья линия addSlotToContainer(new Slot(testTile, 7, 8, 45)); addSlotToContainer(new Slot(testTile, 8, 26, 45)); addSlotToContainer(new Slot(testTile, 9, 44, 45)); //четвёртая линия addSlotToContainer(new Slot(testTile, 10, 8, 63)); addSlotToContainer(new Slot(testTile, 11, 26, 63)); addSlotToContainer(new Slot(testTile, 12, 44, 63)); //Слот 1 (Шаблон) Слот 2 (Материал) Слот 3 (Шаблон на материале) addSlotToContainer(new Slot(testTile, 13, 80, 9));// 1 addSlotToContainer(new Slot(testTile, 14, 80, 45));// 2 addSlotToContainer(new Slot(testTile, 15, 128, 27));// 3
У тебя вместо указывания номеров каждого слота есть переменная i
Просто делай i++ вот так:
addSlotToContainer(new Slot(testTile, i++, 8, 9));
UPD2: предметы в гуй не сохраняются после перезахода в мир
По этому была одна тема как раз, щас скину.
 

sk9zist :l

Исправился
981
18
157
@Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); NBTTagList list = new NBTTagList(); for(int i = 0; i < inventory.getSizeInventory(); i++) { if(inventory.getStackInSlot(i) != null) { NBTTagCompound component = new NBTTagCompound(); component.setByte("Slot", (byte)i); inventory.getStackInSlot(i).writeToNBT(component); list.appendTag(component); } } compound.setTag("ItemStaks", list); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); NBTTagList ls = compound.getTagList("ItemStaks", 10); this.inventory = new InventoryBasic("Namer", false, 15); for(int i = 0; i < ls.tagCount(); i++) { NBTTagCompound tag = ls.getCompoundTagAt(i); byte b = tag.getByte("Slot"); if(b >= 0 && b < inventory.getSizeInventory()) { inventory.setInventorySlotContents(b, ItemStack.loadItemStackFromNBT(tag)); } } }
Вот тут идёт сохранение после перезахода. В writeToNBT и readFromNBT сохранение в нбт после выхода.
Во первых:
Замени свой getStackInSlot на:
Java:
public ItemStack getStackInSlot(int p_70301_1_)
{
    return this.stackResult[p_70301_1_];
}
Во вторых:
вот в этой строке:
Java:
private ItemStack[] stackResult = new ItemStack[1];
надо тоже установить значение, которое ты установил в getSizeInventory, тоесть 15
так что замени на это:
Java:
private ItemStack[] stackResult = new ItemStack[15];
Всё должно заработать.
 
Сверху