Просто приведу пример с комментариями, как сделать GuiContainer.

Для того, чтобы у вас было GUI, необходимо прописать под @Mod аннотацию

@NetworkMod(clientSideRequired=true, serverSideRequired=true)
(начиная с 1.7.2 этот пункт пропустить). Также необходимо иметь такие строки в том же классе:

@Instance("MODID")//Обязательно точно такую же строку, как и в @Mod(modid= !
public static ModClass anyName;//Переменная вашего класса в любым названием(чаще всего instance, на 2 месте mod)

После создания класса GuiHandler пропишем такую строку в метод init:
до 1.7 - NetworkRegistry.instance().registerGuiHandler(instance, new GuiHandler());
1.7 - NetworkRegistry.INSTANCE.registerGuiHandler(instance, new GuiHandler());

GuiHandler:
Код:
public class GuiHandler implements IGuiHandler{

    public Object getServerGuiElement(int id, EntityPlayer player, World wrd, int x, int y, int z){
        switch(id){//В зависимости от id выбираем контейнер
            case 1://
                return new ContainerTest(player);//Вместо player можем дать что угодно, TileEntity, ItemStack предмета(сумки например), это же ваш класс с вашим конструктором
            default:
                return null;
        }
    }

    public Object getClientGuiElement(int id, EntityPlayer player, World wrd, int x, int y, int z){
        switch(id){//В зависимости от id выбираем gui
            case 1:
                return new GuiTest(player);//Важно, дать те же параметры, что и контейнеру, в классе GUI увидите
            default:
                return null;
        }
    }
}

Что-бы открыть ваше gui, вам нужен игрок, на сервере выполняем такой метод(там, где хотите открыть, разумеется)
player.openGui(ModClass.instance, 1/*id вашего gui*/, null/*тут необязательно можно дать World, который вам дадут в GuiHandler-е*/, -1, -1, -1 /*Тоже самое, что и с World, но коорды блока так передать можно(чтоб достать TileEntity)*/);

Теперь ContainerTest и GuiTest:

ContainerTest:
Код:
public class ContainerTest extends Container{

    public ContainerTest(EntityPlayer player){//Как я и сказал, ваш конструктор - ваши правила
       /*
        * Слоту нужен какой-либо инвентарь(класс, в котором есть implements IInventory), его id в этом инвентаре, и x да y координаты
        * Ниже в качестве теста, да и просто почти везде такое есть - инвентарь игрока
        */
        for(int i = 0; i < 9; i++)//Циклом добавляем 9 слотов хотбара
            addSlotToContainer(new Slot(player.inventory, i, 29/*x координата первого слота(двигаем хотбар)*/ + i * 18, 90/*y координата*/));
        for(int i = 0; i < 3; i++)//Циклами остальной инвентарь
            for(int j = 0; j < 9; j++)
                addSlotToContainer(new Slot(player.inventory, j + i * 9 + 9, 56/*тоже самое, x*/ + j * 18, 24/*y*/ + i * 18));
    }

    public ItemStack transferStackInSlot(EntityPlayer player, int slotID){
        return null; //Это фикс краша из-за шифта, просто его отключает, потом как-нибудь расскажу, можете посмотреть ContainerChest
    }

    public boolean canInteractWith(EntityPlayer player){
        return true; // Меня заставили это всунуть!!(попробуйте удалить, ошибка будет, этот тупой метод abstract)
    }
}

GuiTest:
Код:
public class GuiTest extends GuiContainer{

    final private ResourceLocation texture = new ResourceLocation("modid", "textures/gui/test.png");//Ваши modid и путь к текстуре gui

    public GuiTest(EntityPlayer player){
        super(new ContainerTest(player));//Теперь понятно, зачем такие же параметры?
        xSize = 222;//Тут размеры, сколько на сколько собстно, кликабельная картинка вашего gui(ведь файл текстуры должен быть 256 на 256!)
        ySize = 112;// и до скольки мы обрежем при рендере, чтобы понятно было.
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mX, int mY) {
        int zX = (width - ySize) / 2; //Находим "координаты верхней левой точки прямоугольника с размерами нашей текстуры, который находится в центре экрана"
        int zY = (height - ySize) / 2;// как я это называю
        mc.getTextureManager().bindTexture(texture);//Ну это понятно
        drawTexturedModalRect(zX, zY, 0, 0, xSize, ySize);//Отрисовываем на "тех самых координатах" картинку, начиная с 0, 0 координаты тестуры(u, v) и размерами, которые мы указали
    }
}

Вот и ВСЕ.
Чтобы добавить - пишем 2 новых класса и потом новый case в GuiHandler-е. Так-же покопайтесь в методах GuiContainer, дабы что-то переписать, типа нарисовать текст и так далее.

P.S.: туториал со старого форума, думаю пригодится.
P.P.S.: автор - anti344
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
А автора указать? =)
 
Дима, новички нет. А олдфаги да)
[merge_posts_bbcode]Добавлено: 10.04.2014 01:23:16[/merge_posts_bbcode]

А ContainerUpdate ошибку пишет...(ps. копипаст, в ручную ничего не писал)
 
905
5
Ну, во-первых, насколько я помню, в ванильке в canInteractWith стоит еще одна проверка на дистанцию открывания.
Во-вторых, в registerGuiHandler первый аргумент - инстанс мода. Люди не поймут же :D
В гуе можно отметить метод drawGuiContainerForegroundLayer - для отрисовки пламени в печке, текста и прочей хрени, которую на бэкграунде не отрисуешь, мерцать будет с оптифайном.
В контейнере можно отметить addCraftingToCrafters, updateProgressBar и detectAndSendChanges, которыми можно синхронизировать ТЕ, если пакеты пилить лень.
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
ДАЛАДНОБЛИН. А теперь перечитай название.
[merge_posts_bbcode]Добавлено: 10.04.2014 13:19:46[/merge_posts_bbcode]

И в ванильке она стоит хрен знает зачем.

[merge_posts_bbcode]Добавлено: 10.04.2014 13:20:30[/merge_posts_bbcode]

... названием(чаще всего instance ...

[merge_posts_bbcode]Добавлено: 10.04.2014 13:20:58[/merge_posts_bbcode]

А теперь спроси у RaVeN-a, что такое синхронизация TE.
 
так... а метод как замутить и куда, что бы выполнить player.openGui? У меня так в файле блока
Код:
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player)
player.openGui(MoreFood.instance, 1, null, -1, -1, -1)
}
И как при моей первой попытке, ничего не получилось. Не открывает.
 
Gui вообще не открывается? Какая версия и есть ли что-то в консоли при попытке открытия?
 
Ага. нашел проблему глубже.
Код:
  switch(id){//В зависимости от id выбираем gui
            case 1:
                return new MincerGui(player);//Важно, дать те же параметры, что и контейнеру, в классе GUI увидите
            default:
                return;
        }
что в ретурн в дефолте пилить? на две переменные x и y матом, а xSize и ySize не принимает. Как?
 
В дефолте null, туда попадает если переменная id не равна ни одному числу, которые проверяются в case'ах
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
X_X совсем люди слепые.
Код:
default:
    return null;
Скопипастил из тутора, как ни странно.
 
Ну не пашет. Регал в блоке
Код:
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player){
    player.openGui(MoreFood.instance, 1, null, 1, 1, 1);
}
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
И какой кнопкой мыши нажимал на блок?
 
Поставь в нужных местах вывод чего-либо в консоль и выясни где не выполняется код.
[merge_posts_bbcode]Добавлено: 15.04.2014 22:36:44[/merge_posts_bbcode]

anti344 написал(а):
И какой кнопкой мыши нажимал на блок?
Кстати да, onBlockClicked это левая кнопка, а onBlockActivated - правая.
 
аааааа... тоесть мне название с onBlockClicked на onBlockActivated менять?
[merge_posts_bbcode]Добавлено: 15.04.2014 23:27:51[/merge_posts_bbcode]

А в какой файл надо метод клика мутить? А то походу именно он не пашет.
 
В блоке. Вот код
Код:
public class Mincer extends BlockContainer{

    public Mincer(int par1, Material par2Material) {
        super(par1, par2Material);
        this.setCreativeTab(MoreFood.mFoodBlocks);
    }
       
@Override
public TileEntity createNewTileEntity(World wrd) {
   return new TileEntityMincer();
}

public int getRenderType() {
   return MoreFood.renderBlockMincerModelID;
}
public boolean isOpaqueCube() {
   return false;
}
public boolean renderAsNormalBlock() {
   return false;
}

public void onBlockActivated(World world, int x, int y, int z, EntityPlayer player){
    player.openGui(MoreFood.instance, 1, null, 1, 1, 1);
    System.out.println("Пашет");
}

public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack)
{
    int l = MathHelper.floor_double((double)(par5EntityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
    int i1 = par1World.getBlockMetadata(par2, par3, par4) & 4;

    if (l == 0)
    {
        par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | i1, 2);
    }

    if (l == 1)
    {
        par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | i1, 2);
    }

    if (l == 2)
    {
        par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | i1, 2);
    }

    if (l == 3)
    {
        par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | i1, 2);
    }
}

public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity, TileEntityMincer entityMincer)
{
    float f = 0.14F;
    float f1 = 0.2F;
    float f2 = 0.8F;
    float f3 = 0.87F;
    int metadata = entityMincer.getBlockMetadata();
    
    
    if(metadata == 0){
        setBlockBounds(f, 0.0F, f1, f3, 0.6f, f2);
        super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    }
    
    if(metadata == 1){
        setBlockBounds(f, 0.0f, f1, f3, 0.6f, f2);
        super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    }
}

public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) {
    
if(iblockaccess.getBlockMetadata(i, j, k) == 0){
    setBlockBounds(0.14F, 0.0F, 0.2F, 0.87F, 0.6F, 0.8F);
}
if(iblockaccess.getBlockMetadata(i, j, k) == 2){
    setBlockBounds(0.2F, 0.0F, 0.14F, 0.8F, 0.6F, 0.87F);
}
if(iblockaccess.getBlockMetadata(i, j, k) == 1){
    setBlockBounds(0.14F, 0.0F, 0.2F, 0.87F, 0.6F, 0.8F);
}

if(iblockaccess.getBlockMetadata(i, j, k) == 3){
    setBlockBounds(0.2F, 0.0F, 0.14F, 0.8F, 0.6F, 0.87F);
}


}


public AxisAlignedBB setCollisionBoundingBoxFromPool(World world, int i, int j, int k) {


return super.getCollisionBoundingBoxFromPool(world, i, j, k);


}


}
 
Сверху