use of cn.nukkit.item.Item in project Nukkit by Nukkit.
the class PlayerInventory method sendCreativeContents.
public void sendCreativeContents() {
if (!(this.getHolder() instanceof Player)) {
return;
}
Player p = (Player) this.getHolder();
InventoryContentPacket pk = new InventoryContentPacket();
pk.inventoryId = ContainerIds.CREATIVE;
if (!p.isSpectator()) {
// fill it for all gamemodes except spectator
pk.slots = Item.getCreativeItems().stream().toArray(Item[]::new);
}
p.dataPacket(pk);
}
use of cn.nukkit.item.Item in project Nukkit by Nukkit.
the class ShapedRecipe method matchInputMap.
private boolean matchInputMap(Item[][] input) {
Map<Integer, Map<Integer, Item>> map = this.getIngredientMap();
// match the given items to the requested items
for (int y = 0, y2 = this.getHeight(); y < y2; ++y) {
for (int x = 0, x2 = this.getWidth(); x < x2; ++x) {
Item given = input[y][x];
Item required = map.get(y).get(x);
if (given == null || !required.equals(given, required.hasMeta(), required.hasCompoundTag()) || required.getCount() != given.getCount()) {
return false;
}
input[y][x] = null;
}
}
// check if there are any items left in the grid outside of the recipe
for (Item[] items : input) {
for (Item item : items) {
if (item != null && !item.isNull()) {
return false;
}
}
}
return true;
}
use of cn.nukkit.item.Item in project Nukkit by Nukkit.
the class ShapelessRecipe method removeIngredient.
public ShapelessRecipe removeIngredient(Item item) {
for (Item ingredient : this.ingredients) {
if (item.getCount() <= 0) {
break;
}
if (ingredient.equals(item, item.hasMeta(), item.getCompoundTag() != null)) {
this.ingredients.remove(ingredient);
item.setCount(item.getCount() - 1);
}
}
return this;
}
use of cn.nukkit.item.Item in project Nukkit by Nukkit.
the class InventoryTransaction method squashDuplicateSlotChanges.
/**
* Iterates over SlotChangeActions in this transaction and compacts any which refer to the same inventorySlot in the same
* inventory so they can be correctly handled.
* <p>
* Under normal circumstances, the same inventorySlot would never be changed more than once in a single transaction. However,
* due to the way things like the crafting grid are "implemented" in MCPE 1.2 (a.k.a. hacked-in), we may get
* multiple inventorySlot changes referring to the same inventorySlot in a single transaction. These multiples are not even guaranteed
* to be in the correct order (inventorySlot splitting in the crafting grid for example, causes the actions to be sent in the
* wrong order), so this method also tries to chain them into order.
*
* @return bool
*/
protected boolean squashDuplicateSlotChanges() {
Map<Integer, List<SlotChangeAction>> slotChanges = new HashMap<>();
for (InventoryAction action : this.actions) {
if (action instanceof SlotChangeAction) {
int hash = Objects.hash(((SlotChangeAction) action).getInventory(), ((SlotChangeAction) action).getSlot());
List<SlotChangeAction> list = slotChanges.get(hash);
if (list == null) {
list = new ArrayList<>();
}
list.add((SlotChangeAction) action);
slotChanges.put(hash, list);
}
}
for (Entry<Integer, List<SlotChangeAction>> entry : new ArrayList<>(slotChanges.entrySet())) {
int hash = entry.getKey();
List<SlotChangeAction> list = entry.getValue();
if (list.size() == 1) {
// No need to compact inventorySlot changes if there is only one on this inventorySlot
slotChanges.remove(hash);
continue;
}
List<SlotChangeAction> originalList = new ArrayList<>(list);
SlotChangeAction originalAction = null;
Item lastTargetItem = null;
for (int i = 0; i < list.size(); i++) {
SlotChangeAction action = list.get(i);
if (action.isValid(this.source)) {
originalAction = action;
lastTargetItem = action.getTargetItem();
list.remove(i);
break;
}
}
if (originalAction == null) {
// Couldn't find any actions that had a source-item matching the current inventory inventorySlot
return false;
}
int sortedThisLoop;
do {
sortedThisLoop = 0;
for (int i = 0; i < list.size(); i++) {
SlotChangeAction action = list.get(i);
Item actionSource = action.getSourceItem();
if (actionSource.equalsExact(lastTargetItem)) {
lastTargetItem = action.getTargetItem();
list.remove(i);
sortedThisLoop++;
} else if (actionSource.equals(lastTargetItem)) {
lastTargetItem.count -= actionSource.count;
list.remove(i);
if (lastTargetItem.count == 0)
sortedThisLoop++;
}
}
} while (sortedThisLoop > 0);
if (list.size() > 0) {
// couldn't chain all the actions together
MainLogger.getLogger().debug("Failed to compact " + originalList.size() + " actions for " + this.source.getName());
return false;
}
for (SlotChangeAction action : originalList) {
this.actions.remove(action);
}
this.addAction(new SlotChangeAction(originalAction.getInventory(), originalAction.getSlot(), originalAction.getSourceItem(), lastTargetItem));
MainLogger.getLogger().debug("Successfully compacted " + originalList.size() + " actions for " + this.source.getName());
}
return true;
}
use of cn.nukkit.item.Item in project Nukkit by Nukkit.
the class CraftingDataPacket method writeShapelessRecipe.
private static int writeShapelessRecipe(ShapelessRecipe recipe, BinaryStream stream) {
stream.putUnsignedVarInt(recipe.getIngredientCount());
for (Item item : recipe.getIngredientList()) {
stream.putSlot(item);
}
stream.putUnsignedVarInt(1);
stream.putSlot(recipe.getResult());
stream.putUUID(recipe.getId());
return CraftingDataPacket.ENTRY_SHAPELESS;
}
Aggregations