timaxa007
Модератор
- 5,831
- 409
- 672
Я уже почти начал создавать, по своему инвентарь Item Storage, но остановился на разные количество слотов. Так как если-бы я продолжал делать, то ещё больше функций и тогда я уже вряд-ли бы выложил хоть какой-то код (или не скоро выложил) связанный с хранением предмете какие-либо вещи.
(github.com) mod backpack 1.7.10
Надеюсь вы знаете как создать свой GuiHandler (у меня во общем другой). У каждого может быть по своему написан GuiHandler, так что постарайтесь понять. В вашем GuiHandler'е:
Контейнер:
Пример взял из ContainerChest.
Пример взял из GuiChest.
В файл "en_US.lang" вписать "inventory.backpack.name=Backpack Inventory.".
В файл "ru_RU.lang" вписать "inventory.backpack.name=Инвентарь Рюкзака".
Функции инвентаря:
Пример взял из InventoryBasic.
Этот код можно записать для Эвента или в апдейт предмета (у меня в Эвенте):
Эвант
Клиентский Эвент - в случаи если не сработало на эвенте или апдейте предмета выше (или перестраховка в случаи высокого TPS):
Надеюсь вы знаете как зарегистрировать предмет. Предмет:
Как приблизительно должны выглядят рецепты:
На сервере не проверялось!!!
(github.com) mod backpack 1.7.10
Надеюсь вы знаете как создать свой GuiHandler (у меня во общем другой). У каждого может быть по своему написан GuiHandler, так что постарайтесь понять. В вашем GuiHandler'е:
В метод "getServerGuiElement":
В метод "getClientGuiElement":
Код:
return new ItemStorageContainer(player, new InventoryItemStorage(current));
В метод "getClientGuiElement":
Код:
return new ItemStorageGui(player, new InventoryItemStorage(current));
Код:
ItemStack current = player.getCurrentEquippedItem();
if (current != null) {
}
Контейнер:
Код:
public class ContainerItemStorage extends net.minecraft.inventory.Container {
private InventoryItemStorage inv;
private int numRows;
public ContainerItemStorage(EntityPlayer player, InventoryItemStorage inventoryItemStorage) {
inv = inventoryItemStorage;
inv.openInventory();//Типа инициализируем открытия инвентаря
numRows = inv.getSizeInventory() / 9;
int i = (numRows - 4) * 18;
int j;
int k;
//Слоты инвентаря Item Storage
for (int id = 0; id < inv.getSizeInventory(); ++id) {
addSlotToContainer(new StorageSlot(inv, id, 8 + (id % 9) * 18, 18 + (id / 9) * 18));
}
//Слоты инвентаря игрока
for (j = 0; j < 3; ++j) {
for (k = 0; k < 9; ++k) {
addSlotToContainer(new SlotNoTakeStorage(player.inventory, k + j * 9 + 9, 8 + k * 18, 103 + j * 18 + i));
}
}
//Слоты хот-бара игрока
for (j = 0; j < 9; ++j) {
addSlotToContainer(new SlotNoTakeStorage(player.inventory, j, 8 + j * 18, 161 + i));
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return inv.isUseableByPlayer(player);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int slot_i) {
ItemStack is = null;
Slot slot = (Slot)inventorySlots.get(slot_i);
if (slot != null && slot.getHasStack()) {
ItemStack is1 = slot.getStack();
is = is1.copy();
//Или иначе по шифт-клику можно было засунуть в наш рюкзак ещё один рюкзак.
if (is1.getItem() instanceof ItemBackpack) return null;
if (slot_i < inv.getSizeInventory()) {
if (!mergeItemStack(is1, inv.getSizeInventory(), inventorySlots.size(), true)) return null;
} else if (!mergeItemStack(is1, 0, inv.getSizeInventory(), false))
return null;
if (is1.stackSize == 0) slot.putStack((ItemStack)null);
else slot.onSlotChanged();
}
return is;
}
@Override
public ItemStack slotClick(int slot, int button, int modifier, EntityPlayer player) {
if (modifier == 2) return null;//Блокируем возможность использование игроком цифровых кнопок, чтобы не было попытки подмены
return super.slotClick(slot, button, modifier, player);
}
@Override
public void onContainerClosed(EntityPlayer player) {
super.onContainerClosed(player);
inv.closeInventory();//Типа инициализируем закрытия инвентаря
}
public void update(EntityPlayer player) {
if (inv != null) inv.update(player);
}
}
Код:
public class StorageSlot extends Slot {
public StorageSlot(IInventory inv, int id, int x, int y) {
super(inv, id, x, y);
}
//Нельзя поставить в этот слот предмет с экземпляром ItemBackpack.
//В дальнейшем я тут буду добавлять, чтобы нельзя из других модов вставлять предметы с хранением вещей.
@Override
public boolean isItemValid(ItemStack is) {
return (is != null && is.getItem() instanceof ItemBackpack) ? false : super.isItemValid(is);
}
}
Код:
public class SlotNoTakeStorage extends Slot {
public SlotNoTakeStorage(IInventory inv, int id, int x, int y) {
super(inv, id, x, y);
}
//Нельзя взять из этого слота, если это находиться в руке игрока.
//Хотя по стандарту, можно только для хот-бара, но я не уверен на счёт других модов.
@Override
public boolean canTakeStack(EntityPlayer player) {
ItemStack is = inventory.getStackInSlot(getSlotIndex());
if (is != null && is == player.getCurrentEquippedItem()) return false;
return super.canTakeStack(player);
}
}
Код:
public class GuiItemStorage extends GuiContainer {
private static final ResourceLocation field_147017_u = new ResourceLocation("textures/gui/container/generic_54.png");
private int inventoryRows;
private InventoryPlayer inv_p;
private InventoryItemStorage inv;
public GuiItemStorage(EntityPlayer player, InventoryItemStorage inventoryItemStorage) {
super(new timaxa007.backpack.inventory.ContainerItemStorage(player, inventoryItemStorage));
inv_p = player.inventory;
inv = inventoryItemStorage;
inventoryRows = inventoryItemStorage.getSizeInventory() / 9;
short short1 = 222;
int i = short1 - 108;
ySize = i + inventoryRows * 18;
}
@Override
public void drawGuiContainerForegroundLayer(int i1, int i2) {
//Именование инвентаря Item Storage
if (inv != null) fontRendererObj.drawString(
(inv.hasCustomInventoryName() ? inv.getInventoryName() : StatCollector.translateToLocal("inventory.backpack.name")), 8, 6, 4210752);
//Именование инвентаря игрока
if (inv_p != null) fontRendererObj.drawString(
StatCollector.translateToLocal("container.inventory"), 8, inventoryRows * 18 + 19, 4210752);
}
@Override
public void drawGuiContainerBackgroundLayer(float i1, int i2, int i3) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(field_147017_u);
int k = (width - xSize) / 2;
int l = (height - ySize) / 2;
drawTexturedModalRect(k, l, 0, 0, xSize, inventoryRows * 18 + 17);
drawTexturedModalRect(k, l + inventoryRows * 18 + 17, 0, 126, xSize, 96);
}
}
В файл "en_US.lang" вписать "inventory.backpack.name=Backpack Inventory.".
В файл "ru_RU.lang" вписать "inventory.backpack.name=Инвентарь Рюкзака".
Функции инвентаря:
Код:
public class InventoryItemStorage implements IInventory {
final ItemStack current;//Предмет в котором будет хранить вещи
ItemStack[] inventory;//Массив слотов инвентаря в виде ItemStack
boolean isSave = false;
public InventoryItemStorage(ItemStack is) {
current = is;
if (!current.hasTagCompound()) current.setTagCompound(new NBTTagCompound());
load(current);
//openInventory();
}
@Override
public int getSizeInventory() {
return inventory.length;//Количество слотов инвентаря
}
@Override
public ItemStack getStackInSlot(int slot_id) {
return slot_id >= 0 && slot_id < inventory.length ? inventory[slot_id] : null;
}
@Override
public ItemStack decrStackSize(int slot, int amount) {
if (inventory[slot] != null) {
ItemStack is;
if (inventory[slot].stackSize <= amount) {
is = inventory[slot];
inventory[slot] = null;
markDirty();
return is;
} else {
is = inventory[slot].splitStack(amount);
if (inventory[slot].stackSize == 0) inventory[slot] = null;
markDirty();
return is;
}
} else return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot_id) {
if (inventory[slot_id] != null) {
ItemStack itemstack = inventory[slot_id];
inventory[slot_id] = null;
return itemstack;
} else return null;
}
@Override
public void setInventorySlotContents(int slot_id, ItemStack is) {
inventory[slot_id] = is;
if (is != null && is.stackSize > getInventoryStackLimit())
is.stackSize = getInventoryStackLimit();
markDirty();
}
@Override
public String getInventoryName() {
return current.getDisplayName();//Своё имя
}
@Override
public boolean hasCustomInventoryName() {
return current.hasDisplayName();//Есть-ли своё имя
}
@Override
public int getInventoryStackLimit() {
return 64;//Лимит размер стака в слоте
}
@Override
public void markDirty() {
if (!isSave) isSave = true;
}
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
//Может-ли игрок использовать этот инвентарь
return true;
}
//Открытие инвентаря
@Override
public void openInventory() {
//load();
}
//Закрытие инвентаря
@Override
public void closeInventory() {
//save();
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack is) {
//Можно-ли взаимодействовать со слотом(-ами).
return true;
}
//Методы "load" должны из предмета брать нужные теги для простой работы с инвентарём.
public void load() {
load(current);
}
public void load(ItemStack is) {
load(is.getTagCompound());
}
public void load(NBTTagCompound nbt) {
if (nbt != null) {
NBTTagList nbttaglist = nbt.getTagList("Items", NBT.TAG_COMPOUND);
//Мне так показалось проще сделать, чем брать значение из "nbttagcompound1.getByte("Slot")"
//Наш NBT тег из которого будем брать максимальное количества слотов для нашего инвентаря Item Storage
//Желательно, чтобы размеры инвентаря были [9 * n]
if (nbt.hasKey("CustomSize", NBT.TAG_BYTE))
inventory = new ItemStack[nbt.getByte("CustomSize") & 255];
//Если нету нужно тега, то замер инвентаря Item Storage будет в 27 слотов.
else inventory = new ItemStack[(9 * 3)];
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
int j = nbttagcompound1.getByte("Slot") & 255;
if (j >= 0 && j < inventory.length)
inventory[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
}
//Методы "save" должны в предмет сохранять инвентарь Item Storage в теги.
public void save() {
/*current = */save(current);
}
public void save(ItemStack is) {
/*if (is != null && current != null) {
NBTTagCompound nbt = save(current.getTagCompound());
if (nbt != null) is.setTagCompound(nbt);
return current;
}*/
/*
NBTTagCompound nbt = current.getTagCompound();
save(nbt);
is.setTagCompound(nbt);
*/
save(is.getTagCompound());
//return is;
}
public void save(NBTTagCompound nbt) {
NBTTagList nbttaglist = new NBTTagList();
nbt.setByte("CustomSize", (byte)getSizeInventory());
for (int i = 0; i < inventory.length; ++i) {
if (inventory[i] != null) {
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
inventory[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
nbt.setTag("Items", nbttaglist);
}
public void update(EntityPlayer player) {
if (isSave) {
save();
player.inventory.setInventorySlotContents(player.inventory.currentItem, current);
isSave = false;
}
}
}
Этот код можно записать для Эвента или в апдейт предмета (у меня в Эвенте):
Код:
ItemStack current = player.getCurrentEquippedItem();
Container con = player.openContainer;
if (con != null) {
//-----------------------------------------------------------------------------------
if (con instanceof ItemStorageContainer) {
ItemStorageContainer bc = (ItemStorageContainer)con;
ItemStack new_is = bc.update(player);
if (new_is != null) current = new_is;
//Закрытия окна, в случаи если предмета нет нужного нам предмета.
if (new_is == null || !(new_is != null && new_is.getItem() instanceof ItemBackpack))
player.closeScreen();
}
//------------------------------------------------------------------------------------
}
Эвант
Код:
@SubscribeEvent
public void actiCon(TickEvent.PlayerTickEvent e) {
EntityPlayer player = e.player;
if (player != null) {
//Сюда код
}
}
Код:
@Override
public void onUpdate(ItemStack is, World world, Entity entity, int tick, boolean flag) {
if (!world.isRemote && entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer)entity;
//Суда код
}
}
Клиентский Эвент - в случаи если не сработало на эвенте или апдейте предмета выше (или перестраховка в случаи высокого TPS):
---(Не обязателен к использованию)---
Код:
public class EventItemStorageClient {
//--------------------------------------------------------------------------------------
@SubscribeEvent
public void closeGUI(TickEvent.PlayerTickEvent e) {
if (e.side == Side.CLIENT) {//Данный метод для клиентской стороны
EntityPlayer player = e.player;
if (player != null) {
ItemStack current = player.getCurrentEquippedItem();
GuiScreen gui = FMLClientHandler.instance().getClient().currentScreen;
if (gui != null) {
//---------------------------------------------------------------------------------------
if (gui instanceof ItemStorageGui) {
//Закрытия окна, в случаи если предмета нет нужного нам предмета.
if (current == null || !(current != null && current.getItem() instanceof IItemStorage))
player.closeScreen();
}
//---------------------------------------------------------------------------------------
}
}
}
}
//---------------------------------------------------------------------------------------
}
Надеюсь вы знаете как зарегистрировать предмет. Предмет:
Код:
public static Item backpack = new ItemBackpack().setUnlocalizedName("backpack").setCreativeTab(CreativeTabs.tabMisc).setMaxStackSize(1).setTextureName(MODID + ":backpack");
Код:
public class ItemBackpack extends Item {
public ItemStack onItemRightClick(ItemStack is, World world, EntityPlayer player) {
if (player.isSneaking()) {
} else {
GuiHandler.openGui(GuiHandler.GuiID.BACKPACK, player);
}
return super.onItemRightClick(is, world, player);
}
@SideOnly(Side.CLIENT)
public void getSubItems(Item id, CreativeTabs table, List list) {
//list.add(new ItemStack(id, 1, 0));
list.add(addNBT(new ItemStack(id, 1, 0), 1));
list.add(addNBT(new ItemStack(id, 1, 0), 3));
list.add(addNBT(id, SizeStorage.SIZE1));
list.add(addNBT(id, SizeStorage.SIZE2));
list.add(addNBT(id, SizeStorage.SIZE3));
list.add(addNBT(id, SizeStorage.SIZE4));
list.add(addNBT(id, SizeStorage.SIZE5));
list.add(addNBT(id, SizeStorage.SIZE6));
list.add(addNBT(id, SizeStorage.SIZE7));
list.add(addNBT(id, SizeStorage.SIZE8));
list.add(addNBT(id, SizeStorage.SIZE9));
}
public void addInformation(ItemStack is, EntityPlayer player, List list, boolean flag) {
NBTTagCompound nbt = is.getTagCompound();
if (nbt != null && nbt.hasKey("CustomSize")) list.add("Slots: " + (int)(nbt.getByte("CustomSize") & 255) + ".");
}
public static ItemStack addNBT(Item item, SizeStorage size) {
return addNBT(new ItemStack(item, 1, 0), size);
}
public static ItemStack addNBT(ItemStack is, SizeStorage size) {
return addNBT(is, size.getSize());
}
public static ItemStack addNBT(ItemStack is, int size) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setByte("CustomSize", (byte)size);
is.setTagCompound(nbt);
return is;
}
public static enum SizeStorage {
SIZE1(9),//(9 * 1)
SIZE2(18),//(9 * 2)
SIZE3(27),//(9 * 3)//размеры как у одинарного сундука
SIZE4(36),//(9 * 4)
SIZE5(45),//(9 * 5)
SIZE6(54),//(9 * 6)//размеры как у двойного сундука
SIZE7(63),//(9 * 7)
SIZE8(72),//(9 * 8)
SIZE9(81);//(9 * 9)
private final int size;
SizeStorage(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
}
Как приблизительно должны выглядят рецепты:
Код:
GameRegistry.addRecipe(ItemStorage.addNBT(PackFurniture.item.storage, ItemStorage.size_storage.SIZE1), new Object[]{
"SLS", "LSL", 'L', Items.leather, 'S', Items.string});
GameRegistry.addRecipe(ItemStorage.addNBT(PackFurniture.item.storage, ItemStorage.size_storage.SIZE2), new Object[]{
"SSS", "L L", "LCL", 'L', Items.leather, 'S', Items.string, 'C', Blocks.carpet});
GameRegistry.addRecipe(ItemStorage.addNBT(PackFurniture.item.storage, ItemStorage.size_storage.SIZE3), new Object[]{
"LSL", "SWS", "LLL", 'L', Items.leather, 'W', Blocks.wool, 'S', Items.string});
GameRegistry.addRecipe(ItemStorage.addNBT(PackFurniture.item.storage, ItemStorage.size_storage.SIZE4), new Object[]{
"LLL", "WCW", "LLL", 'L', Items.leather, 'W', Blocks.carpet, 'C', Blocks.chest});
На сервере не проверялось!!!
Последнее редактирование: