package <пакет>;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import <пакет>.TileEntityTest;
public class ContainerTest extends Container {
private TileEntityTest tile;
/**
* В аргументы указывается инвентарь игрока и TileEntity, который мы открыли
*/
public...
Мне необходим именно 1.7.10, я не такой профикодер, чтобы заменить методы.В плане гуи тоже самое, не надо тут. Все те же методы
Не удержался
package <пакет>;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import <пакет>.TileEntityTest;
public class ContainerTest extends Container {
private TileEntityTest tile;
/**
* В аргументы указывается инвентарь игрока и TileEntity, который мы открыли
*/
public ContainerTest(InventoryPlayer player, TileEntityTest 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);
}
}
package <пакет>;
import org.lwjgl.opengl.GL11;
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 <пакет>.TileEntityTest;
import <пакет>.ContainerTest;
public class GuiTest extends GuiContainer {
/** Текстура GUI */
private static final ResourceLocation textures = new ResourceLocation(
MODID, "textures/gui/container/<name>.png");
private TileEntityTest tile;
public GuiTest(InventoryPlayer player, TileEntityTest tileTest) {
// Сюда указать объект контейнера.
super(new ContainerTest(player, tile));
// Сохраняем 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);
}
}
package <пакет>;
import cpw.mods.fml.common.network.IGuiHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import <пакет>.TileEntityTest;
import <пакет>.ContainerTest;
import <пакет>.GuiTest;
public class TestGuiHandler 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 TileEntityTest)
return new ContainerTest(player.inventory, (TileEntityTest) 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 TileEntityTest)
return new GuiTest(player.inventory, (TileEntityTest) tile);
return null;
}
}
public void init(FMLInitializationEvent event) {
// Инстанция мода и объект GuiHandler'а.
NetworkRegistry.INSTANCE.registerGuiHandler(TESTMOD.instance, new TestGuiHandler());
}
@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(TESTMOD.instance, GUIID, world, x, y, z);
return true;
}
}
return false;
}
Сейчас этим занялся, у меня вопрос, что за TileEntity? :/Короче, дело такое (разумеется, объясняю создание GUI для инвентарных TileEntity):
Делаешь класс, наследующий Container:
Java:package <пакет>; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import <пакет>.TileEntityTest; public class ContainerTest extends Container { private TileEntityTest tile; /** * В аргументы указывается инвентарь игрока и TileEntity, который мы открыли */ public ContainerTest(InventoryPlayer player, TileEntityTest 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); } }
Затем, создаешь класс для самого GUI:
Java:package <пакет>; import org.lwjgl.opengl.GL11; 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 <пакет>.TileEntityTest; import <пакет>.ContainerTest; public class GuiTest extends GuiContainer { /** Текстура GUI */ private static final ResourceLocation textures = new ResourceLocation( MODID, "textures/gui/container/<name>.png"); private TileEntityTest tile; public GuiTest(InventoryPlayer player, TileEntityTest tileTest) { // Сюда указать объект контейнера. super(new ContainerTest(player, tile)); // Сохраняем 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); } }
Теперь, чтобы всё это работало нужно создать GuiHandler:
Java:package <пакет>; import cpw.mods.fml.common.network.IGuiHandler; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import <пакет>.TileEntityTest; import <пакет>.ContainerTest; import <пакет>.GuiTest; public class TestGuiHandler 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 TileEntityTest) return new ContainerTest(player.inventory, (TileEntityTest) 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 TileEntityTest) return new GuiTest(player.inventory, (TileEntityTest) tile); return null; } }
Не забудь зарегистрировать его:
Java:public void init(FMLInitializationEvent event) { // Инстанция мода и объект GuiHandler'а. NetworkRegistry.INSTANCE.registerGuiHandler(TESTMOD.instance, new TestGuiHandler()); }
Чтобы вызвать GUI кликом по блоку, добавь этот код в свой блок:
Java:@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(TESTMOD.instance, GUIID, world, x, y, z); return true; } } return false; }
-----------
Да, тебе придётся немного подкорректировать. Кстати, могут быть недочёты, я писал в блокноте ¯\_(ツ)_/¯
TileEntity - это "сущность" (само название говорит). Она нужна для того чтобы хранить в себе данные (для игрока, например, - это мана и HP) и обновляться каждый тик. Я думаю, что тебе следует немного покурить мануалы вот тут, перед тем как заниматься GUI.Сейчас этим занялся, у меня вопрос, что за TileEntity? :/