All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.inventory.PlayerInventory Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.inventory;

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockID;
import cn.nukkit.entity.EntityHuman;
import cn.nukkit.entity.EntityHumanType;
import cn.nukkit.event.entity.EntityArmorChangeEvent;
import cn.nukkit.event.entity.EntityInventoryChangeEvent;
import cn.nukkit.event.player.PlayerItemHeldEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemArmor;
import cn.nukkit.item.ItemBlock;
import cn.nukkit.level.vibration.VibrationEvent;
import cn.nukkit.level.vibration.VibrationType;
import cn.nukkit.network.protocol.*;
import cn.nukkit.network.protocol.types.ContainerIds;

import java.util.Collection;

/**
 * 0-8 物品栏
* 9-35 背包
* 36-39 盔甲栏
* 想获取副手库存请用{@link PlayerOffhandInventory}
* * @author MagicDroidX (Nukkit Project) */ public class PlayerInventory extends BaseInventory { protected int itemInHandIndex = 0; private int[] hotbar; public PlayerInventory(EntityHumanType player) { super(player, InventoryType.PLAYER); this.hotbar = new int[this.getHotbarSize()]; for (int i = 0; i < this.hotbar.length; i++) { this.hotbar[i] = i; } } @Override public int getSize() { return super.getSize() - 4; } @Override public void setSize(int size) { super.setSize(size + 4); this.sendContents(this.getViewers()); } /** * Called when a client equips a hotbar inventorySlot. This method should not be used by plugins. * This method will call PlayerItemHeldEvent. * * @param slot hotbar slot Number of the hotbar slot to equip. * @return boolean if the equipment change was successful, false if not. */ public boolean equipItem(int slot) { if (!isHotbarSlot(slot)) { this.sendContents((Player) this.getHolder()); return false; } if (this.getHolder() instanceof Player) { Player player = (Player) this.getHolder(); PlayerItemHeldEvent ev = new PlayerItemHeldEvent(player, this.getItem(slot), slot); this.getHolder().getLevel().getServer().getPluginManager().callEvent(ev); if (ev.isCancelled()) { this.sendContents(this.getViewers()); return false; } if (player.fishing != null) { if (!(this.getItem(slot).equals(player.fishing.rod))) { player.stopFishing(false); } } } this.setHeldItemIndex(slot, false); return true; } private boolean isHotbarSlot(int slot) { return slot >= 0 && slot <= this.getHotbarSize(); } @Deprecated public int getHotbarSlotIndex(int index) { return index; } @Deprecated public void setHotbarSlotIndex(int index, int slot) { } public int getHeldItemIndex() { return this.itemInHandIndex; } public void setHeldItemIndex(int index) { setHeldItemIndex(index, true); } public void setHeldItemIndex(int index, boolean send) { if (index >= 0 && index < this.getHotbarSize()) { this.itemInHandIndex = index; if (this.getHolder() instanceof Player && send) { this.sendHeldItem((Player) this.getHolder()); } this.sendHeldItem(this.getHolder().getViewers().values()); } } public Item getItemInHand() { Item item = this.getItem(this.getHeldItemIndex()); if (item != null) { return item; } else { return new ItemBlock(Block.get(BlockID.AIR), 0, 0); } } public boolean setItemInHand(Item item) { return this.setItem(this.getHeldItemIndex(), item); } @Deprecated public int getHeldItemSlot() { return this.itemInHandIndex; } public void setHeldItemSlot(int slot) { if (!isHotbarSlot(slot)) { return; } this.itemInHandIndex = slot; if (this.getHolder() instanceof Player) { this.sendHeldItem((Player) this.getHolder()); } this.sendHeldItem(this.getViewers()); } public void sendHeldItem(Player... players) { Item item = this.getItemInHand(); MobEquipmentPacket pk = new MobEquipmentPacket(); pk.item = item; pk.inventorySlot = pk.hotbarSlot = this.getHeldItemIndex(); for (Player player : players) { pk.eid = this.getHolder().getId(); if (player.equals(this.getHolder())) { pk.eid = player.getId(); this.sendSlot(this.getHeldItemIndex(), player); } player.dataPacket(pk); } } public void sendHeldItem(Collection players) { this.sendHeldItem(players.toArray(Player.EMPTY_ARRAY)); } @Override public void onSlotChange(int index, Item before, boolean send) { EntityHuman holder = this.getHolder(); if (holder instanceof Player && !((Player) holder).spawned) { return; } if (index >= this.getSize()) { this.sendArmorSlot(index, this.getViewers()); this.sendArmorSlot(index, this.getHolder().getViewers().values()); if (this.getItem(index) instanceof ItemArmor) { this.getHolder().level.getVibrationManager().callVibrationEvent(new VibrationEvent(getHolder(), this.getHolder().clone(), VibrationType.EQUIP)); } } else { super.onSlotChange(index, before, send); } } public int getHotbarSize() { return 9; } public Item getArmorItem(int index) { return this.getItem(this.getSize() + index); } public boolean setArmorItem(int index, Item item) { return this.setArmorItem(index, item, false); } public boolean setArmorItem(int index, Item item, boolean ignoreArmorEvents) { return this.setItem(this.getSize() + index, item, ignoreArmorEvents); } public Item getHelmet() { return this.getItem(this.getSize()); } public Item getChestplate() { return this.getItem(this.getSize() + 1); } public Item getLeggings() { return this.getItem(this.getSize() + 2); } public Item getBoots() { return this.getItem(this.getSize() + 3); } public boolean setHelmet(Item helmet) { return this.setItem(this.getSize(), helmet); } public boolean setChestplate(Item chestplate) { return this.setItem(this.getSize() + 1, chestplate); } public boolean setLeggings(Item leggings) { return this.setItem(this.getSize() + 2, leggings); } public boolean setBoots(Item boots) { return this.setItem(this.getSize() + 3, boots); } @Override public boolean setItem(int index, Item item) { return setItem(index, item, true, false); } @Override public boolean setItem(int index, Item item, boolean send) { return setItem(index, item, send, false); } private boolean setItem(int index, Item item, boolean send, boolean ignoreArmorEvents) { if (index < 0 || index >= this.size) { return false; } else if (item.getId() == 0 || item.getCount() <= 0) { return this.clear(index); } //Armor change if (!ignoreArmorEvents && index >= this.getSize()) { EntityArmorChangeEvent ev = new EntityArmorChangeEvent(this.getHolder(), this.getItem(index), item, index); Server.getInstance().getPluginManager().callEvent(ev); if (ev.isCancelled() && this.getHolder() != null) { this.sendArmorSlot(index, this.getViewers()); return false; } item = ev.getNewItem(); } else { EntityInventoryChangeEvent ev = new EntityInventoryChangeEvent(this.getHolder(), this.getItem(index), item, index); Server.getInstance().getPluginManager().callEvent(ev); if (ev.isCancelled()) { this.sendSlot(index, this.getViewers()); return false; } item = ev.getNewItem(); } Item old = this.getItem(index); this.slots.put(index, item.clone()); this.onSlotChange(index, old, send); return true; } @Override public boolean clear(int index, boolean send) { if (this.slots.containsKey(index)) { Item item = new ItemBlock(Block.get(BlockID.AIR), null, 0); Item old = this.slots.get(index); if (index >= this.getSize() && index < this.size) { EntityArmorChangeEvent ev = new EntityArmorChangeEvent(this.getHolder(), old, item, index); Server.getInstance().getPluginManager().callEvent(ev); if (ev.isCancelled()) { if (index >= this.size) { this.sendArmorSlot(index, this.getViewers()); } else { this.sendSlot(index, this.getViewers()); } return false; } item = ev.getNewItem(); } else { EntityInventoryChangeEvent ev = new EntityInventoryChangeEvent(this.getHolder(), old, item, index); Server.getInstance().getPluginManager().callEvent(ev); if (ev.isCancelled()) { if (index >= this.size) { this.sendArmorSlot(index, this.getViewers()); } else { this.sendSlot(index, this.getViewers()); } return false; } item = ev.getNewItem(); } if (item.getId() != Item.AIR) { this.slots.put(index, item.clone()); } else { this.slots.remove(index); } this.onSlotChange(index, old, send); } return true; } public Item[] getArmorContents() { Item[] armor = new Item[4]; for (int i = 0; i < 4; i++) { armor[i] = this.getItem(this.getSize() + i); } return armor; } @Override public void clearAll() { int limit = this.getSize() + 4; for (int index = 0; index < limit; ++index) { this.clear(index); } getHolder().getOffhandInventory().clearAll(); } public void sendArmorContents(Player player) { this.sendArmorContents(new Player[]{player}); } public void sendArmorContents(Player[] players) { Item[] armor = this.getArmorContents(); MobArmorEquipmentPacket pk = new MobArmorEquipmentPacket(); pk.eid = this.getHolder().getId(); pk.slots = armor; pk.tryEncode(); for (Player player : players) { if (player.equals(this.getHolder())) { InventoryContentPacket pk2 = new InventoryContentPacket(); pk2.inventoryId = InventoryContentPacket.SPECIAL_ARMOR; pk2.slots = armor; player.dataPacket(pk2); } else { player.dataPacket(pk); } } } public void setArmorContents(Item[] items) { if (items.length < 4) { Item[] newItems = new Item[4]; System.arraycopy(items, 0, newItems, 0, items.length); items = newItems; } for (int i = 0; i < 4; ++i) { if (items[i] == null) { items[i] = new ItemBlock(Block.get(BlockID.AIR), null, 0); } if (items[i].getId() == Item.AIR) { this.clear(this.getSize() + i); } else { this.setItem(this.getSize() + i, items[i]); } } } public void sendArmorContents(Collection players) { this.sendArmorContents(players.toArray(Player.EMPTY_ARRAY)); } public void sendArmorSlot(int index, Player player) { this.sendArmorSlot(index, new Player[]{player}); } public void sendArmorSlot(int index, Player[] players) { Item[] armor = this.getArmorContents(); MobArmorEquipmentPacket pk = new MobArmorEquipmentPacket(); pk.eid = this.getHolder().getId(); pk.slots = armor; pk.tryEncode(); for (Player player : players) { if (player.equals(this.getHolder())) { InventorySlotPacket pk2 = new InventorySlotPacket(); pk2.inventoryId = InventoryContentPacket.SPECIAL_ARMOR; pk2.slot = index - this.getSize(); pk2.item = this.getItem(index); player.dataPacket(pk2); } else { player.dataPacket(pk); } } } public void sendArmorSlot(int index, Collection players) { this.sendArmorSlot(index, players.toArray(Player.EMPTY_ARRAY)); } @Override public void sendContents(Player player) { this.sendContents(new Player[]{player}); } @Override public void sendContents(Collection players) { this.sendContents(players.toArray(Player.EMPTY_ARRAY)); } @Override public void sendContents(Player[] players) { InventoryContentPacket pk = new InventoryContentPacket(); pk.slots = new Item[this.getSize()]; for (int i = 0; i < this.getSize(); ++i) { pk.slots[i] = this.getItem(i); } /*//Because PE is stupid and shows 9 less slots than you send it, give it 9 dummy slots so it shows all the REAL slots. for(int i = this.getSize(); i < this.getSize() + this.getHotbarSize(); ++i){ pk.slots[i] = new ItemBlock(Block.get(BlockID.AIR)); } pk.slots[i] = new ItemBlock(Block.get(BlockID.AIR)); }*/ for (Player player : players) { int id = player.getWindowId(this); if (id == -1 || !player.spawned) { if (this.getHolder() != player) this.close(player); continue; } pk.inventoryId = id; player.dataPacket(pk.clone()); } } @Override public void sendSlot(int index, Player player) { this.sendSlot(index, new Player[]{player}); } @Override public void sendSlot(int index, Collection players) { this.sendSlot(index, players.toArray(Player.EMPTY_ARRAY)); } @Override public void sendSlot(int index, Player... players) { InventorySlotPacket pk = new InventorySlotPacket(); pk.slot = index; pk.item = this.getItem(index).clone(); for (Player player : players) { if (player.equals(this.getHolder())) { pk.inventoryId = ContainerIds.INVENTORY; player.dataPacket(pk); } else { int id = player.getWindowId(this); if (id == -1) { this.close(player); continue; } pk.inventoryId = id; player.dataPacket(pk.clone()); } } } public void sendCreativeContents() { if (!(this.getHolder() instanceof Player)) { return; } Player p = (Player) this.getHolder(); CreativeContentPacket pk = new CreativeContentPacket(); if (!p.isSpectator()) { //fill it for all gamemodes except spectator pk.entries = Item.getCreativeItems().toArray(Item.EMPTY_ARRAY); } p.dataPacket(pk); } //由于NK从PlayerInventory中分离了盔甲栏,并且getSize值修改为36,但实际上slots最大容量为40,按照逻辑应该将solts size也减4 @Override public int getFreeSpace(Item item) { int maxStackSize = Math.min(item.getMaxStackSize(), this.getMaxStackSize()); int slots = this.slots.size() > 36 ? this.slots.size() - 4 : this.slots.size(); int space = (this.getSize() - slots) * maxStackSize; for (Item slot : this.getContents().values()) { if (slot == null || slot.getId() == 0) { space += maxStackSize; continue; } if (slot.equals(item, true, true)) { space += maxStackSize - slot.getCount(); } } return space; } @Override public EntityHuman getHolder() { return (EntityHuman) super.getHolder(); } @Override public void onOpen(Player who) { super.onOpen(who); if (who.spawned) { ContainerOpenPacket pk = new ContainerOpenPacket(); pk.windowId = who.getWindowId(this); pk.type = this.getType().getNetworkType(); pk.x = who.getFloorX(); pk.y = who.getFloorY(); pk.z = who.getFloorZ(); pk.entityId = who.getId(); who.dataPacket(pk); } } @Override public void onClose(Player who) { ContainerClosePacket pk = new ContainerClosePacket(); pk.windowId = who.getWindowId(this); pk.wasServerInitiated = who.getClosingWindowId() != pk.windowId; who.dataPacket(pk); // player can never stop viewing their own inventory if (who != holder) { super.onClose(who); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy