- 42
- 8
Всем привет.
Проблема следующая: сделал TileEntity, нужно прикрепить к нему инвентарь. Вроде бы, всё пошло хорошо, реализовал интерфейс IInventory в TE, сделал GUI, контейнер и GUIHandler. Но внезапно возникла конфузная ситуация: внутри самой игры при открытии инвентаря этого TE невозможно взаимодействовать с любыми слотами, при клике предмет сразу же возвращается обратно. Начал раскапывать ситуацию и сделал небольшой дебаггер, сбрасывающий текущий открытый контейнер игрока в консоль каждые 2 секунды и получил следующий результат. Если что, даже пока GUI открыто:
Смутило и начал закапывать ещё глубже - засунул дебаг-код в GUIHandler, получил такой ответ в консоли:
При этом, GUIHandler имеет следующий вид:
Исходя из этого, делаю вывод, что срабатывает только getClientGuiElement. Прикреплю ниже классы контейнера, GUI, блока и TileEntity целиком.
Если кто-то сталкивался с такой проблемой ранее или нашёл в моём коде явную ошибку, то прошу помочь с решением.
Спасибо.
Проблема следующая: сделал TileEntity, нужно прикрепить к нему инвентарь. Вроде бы, всё пошло хорошо, реализовал интерфейс IInventory в TE, сделал GUI, контейнер и GUIHandler. Но внезапно возникла конфузная ситуация: внутри самой игры при открытии инвентаря этого TE невозможно взаимодействовать с любыми слотами, при клике предмет сразу же возвращается обратно. Начал раскапывать ситуацию и сделал небольшой дебаггер, сбрасывающий текущий открытый контейнер игрока в консоль каждые 2 секунды и получил следующий результат. Если что, даже пока GUI открыто:
[Server thread/INFO]: net.minecraft.inventory.ContainerPlayer@131d1a23
EventHandler:
int tickskip = 0;
@SubscribeEvent
public void onPlayerTick(TickEvent.PlayerTickEvent e) {
if(e.side == Side.SERVER) {
if(tickskip >= 40) {
PsLog.info(e.player.openContainer.toString()); // Вывод того сообщения
this.tickskip = 0;
} else tickskip++;
}
}
Смутило и начал закапывать ещё глубже - засунул дебаг-код в GUIHandler, получил такой ответ в консоли:
Вырезка из лога в консоли:
[20:50:07] [Server thread/INFO]: Player877 присоединился к игре
[20:50:11] [Client thread/INFO] Trying to interact client gui element 0 by Player877
[20:50:11] [Client thread/INFO] Opened ru.pentacraft.mrlich.pentasolar.common.tileentities.TileSolarGenerator@3594aadb gui container
[20:50:11] [Server thread/INFO] net.minecraft.inventory.ContainerPlayer@5196ac2
При этом, GUIHandler имеет следующий вид:
GUIHandler:
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
PsLog.info("Trying to interact server gui element "+ID+" by "+player.getDisplayName());
TileEntity te = world.getTileEntity(x, y, z);
if(te != null) {
if(te instanceof TileSolarGenerator) {
PsLog.info("Opened "+te.toString()+" container");
return ((TileSolarGenerator)te).getGuiContainer(player.inventory);
}
}
return null;
}
@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
PsLog.info("Trying to interact client gui element "+ID+" by "+player.getDisplayName());
TileEntity te = world.getTileEntity(x, y, z);
if(te != null) {
if(te instanceof TileSolarGenerator) {
PsLog.info("Opened "+te.toString()+" gui container");
return new GuiSolarGenerator(player.inventory,(TileSolarGenerator)te);
}
}
return null;
}
Исходя из этого, делаю вывод, что срабатывает только getClientGuiElement. Прикреплю ниже классы контейнера, GUI, блока и TileEntity целиком.
Container:
public class ContainerSolarGenerator extends Container {
TileSolarGenerator tile;
public ContainerSolarGenerator(InventoryPlayer playerinventory, TileSolarGenerator tile) {
this.tile = tile;
for (int j = 0; j < 4; j++) {
addSlotToContainer(new Slot(this.tile, j, 17 + j * 18, 59)
{
public boolean isItemValid(ItemStack stack)
{
return (stack == null) || ((stack.getItem() == Items.diamond));
}
});
}
for (int i = 0; i < 3; i++) {
for (int k = 0; k < 9; k++) {
addSlotToContainer(new Slot(playerinventory, k + i * 9 + 9, 17 + k * 18, 86 + i * 18));
}
}
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(playerinventory, j, 17 + j * 18, 144));
}
}
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack stack = null;
Slot slotObject = (Slot)this.inventorySlots.get(par2);
if ((slotObject != null) && (slotObject.getHasStack()))
{
ItemStack stackInSlot = slotObject.getStack();
stack = stackInSlot.copy();
if ((par2 >= 0) && (par2 <= 3))
{
if (!mergeItemStack(stackInSlot, 4, 40, true)) {
return null;
}
}
else if ((par2 >= 4) && (par2 < 31))
{
if ((!mergeItemStack(stackInSlot, 0, 4, false)) && (!mergeItemStack(stackInSlot, 31, 40, false))) {
return null;
}
}
else if ((par2 >= 31) && (par2 < 39))
{
if (!mergeItemStack(stackInSlot, 0, 30, false)) {
return null;
}
}
else if (!mergeItemStack(stackInSlot, 0, 30, false)) {
return null;
}
if (stackInSlot.stackSize == 0) {
slotObject.putStack((ItemStack)null);
} else {
slotObject.onSlotChanged();
}
if (stack.stackSize == stackInSlot.stackSize) {
return null;
}
slotObject.onPickupFromSlot(par1EntityPlayer, stackInSlot);
}
return stack;
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return this.tile.isUseableByPlayer(player);
}
}
GUI:
public class GuiSolarGenerator extends GuiContainer {
public TileSolarGenerator tile;
private static ResourceLocation tex = new ResourceLocation("pentasolar", "textures/gui/GUIAdvancedSolarPanel.png");
public GuiSolarGenerator(InventoryPlayer player, TileSolarGenerator tile) {
super(new ContainerSolarGenerator(player,tile));
this.tile = tile;
this.xSize = 194;
this.ySize = 168;
this.allowUserInput = true;
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.renderEngine.bindTexture(tex);
int h = (this.width - this.xSize) / 2;
int k = (this.height - this.ySize) / 2;
drawTexturedModalRect(h, k, 0, 0, this.xSize, this.ySize);
drawTexturedModalRect(h + 19, k + 24, 195, 0, this.tile.getFillPercent()*24/100 + 1, 14);
}
protected void drawGuiContainerForegroundLayer(int x, int y) {
int nmPos = (this.xSize - this.fontRendererObj.getStringWidth("QR Solar Panel")) / 2;
this.fontRendererObj.drawString("QR Solar Panel", nmPos, 7, 7718655);
this.fontRendererObj.drawString("Storage: "+this.tile.getEnergy()+"/250", 50, 22, 13487565);
}
public void updateScreen()
{
super.updateScreen();
if (this.tile.isInvalid()) {
this.mc.thePlayer.closeScreen();
}
}
}
Block:
public class BlockSolarGenerator extends PsBlock {
IIcon icontop;
IIcon icon;
public BlockSolarGenerator() {
super();
this.setBlockName("solarGenerator");
this.setHardness(2F);
this.setHarvestLevel("pickaxe", 2);
this.setCreativeTab(PentaSolar.creativetab);
PsBlocks.register(this);
}
public boolean isReplaceable(IBlockAccess world, int x, int y, int z)
{
return super.isReplaceable(world, x, y, z);
}
@Override
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister iconRegister)
{
this.icontop = iconRegister.registerIcon(References.RESOURCESPREFIX + "solargenerator_top");
this.icon = iconRegister.registerIcon(References.RESOURCESPREFIX + "solargenerator");
}
@SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) {
if(side == 1) {
return this.icontop;
} else return this.icon;
}
@SideOnly(Side.CLIENT)
public IIcon getIcon(int blockSide, int blockMeta)
{
if(blockSide == 1) {
return this.icontop;
} else return this.icon;
}
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float px, float py, float pz) {
if(world.isRemote) {
if(world.getTileEntity(x, y, z) != null && world.getTileEntity(x, y, z) instanceof TileSolarGenerator) {
if(!player.isSneaking()) {
player.openGui(PentaSolar.instance, 0, world, x, y, z);
return true;
}
}
}
return true;
}
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) {
return Items.diamond;
}
public boolean canSilkHarvest() {
return true;
}
public boolean hasTileEntity(int metadata) {
return true;
}
public TileEntity createTileEntity(World world, int metadata) {
return new TileSolarGenerator();
}
}
TileEntity:
public class TileSolarGenerator extends TileEntityBase implements IInventory {
int energystorage = 0;
ItemStack[] slots;
public TileSolarGenerator() {
this.slots = new ItemStack[4];
}
public void updateEntity() {
if(energystorage < 250) energystorage++;
}
public int getEnergy() {
return this.energystorage;
}
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setInteger("Energy", this.energystorage);
}
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
this.energystorage = tag.getInteger("Energy");
}
@Override
public int getSizeInventory() {
return this.slots.length;
}
@Override
public ItemStack getStackInSlot(int i) {
return this.slots[i];
}
@Override
public ItemStack decrStackSize(int i, int j) {
if (this.slots[i] != null)
{
if (this.slots[i].stackSize <= j)
{
ItemStack itemstack = this.slots[i];
this.slots[i] = null;
return itemstack;
}
ItemStack itemstack1 = this.slots[i].splitStack(j);
if (this.slots[i].stackSize == 0) {
this.slots[i] = null;
}
return itemstack1;
}
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int var1) {
if (this.slots[var1] != null)
{
ItemStack var2 = this.slots[var1];
this.slots[var1] = null;
return var2;
}
return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack is) {
this.slots[i] = is;
this.markDirty();
}
@Override
public String getInventoryName() {
return "Custom Lich`s inventory";
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return entityplayer.getDistance(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64.0D;
}
@Override
public void openInventory() {
}
@Override
public void closeInventory() {
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return (stack != null) && ((stack.getItem() == Items.diamond));
}
public Container getGuiContainer(InventoryPlayer player) {
return new ContainerSolarGenerator(player,this);
}
public int getFillPercent() {
return (int) Math.round(((double)this.energystorage)/250D*100D);
}
}
Если кто-то сталкивался с такой проблемой ранее или нашёл в моём коде явную ошибку, то прошу помочь с решением.
Спасибо.