blob: 941802143cab7d4909258cd1579c4a19863ad771 [file] [log] [blame] [raw]
package net.glowstone.inventory;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
/**
* Tracker for when the equipment of an entity is changed.
*/
@RequiredArgsConstructor
public final class EquipmentMonitor {
/**
* The entity whose equipment is being monitored.
*
* @param entity The entity whose equipment to monitor.
* @return The entity.
*/
@Getter
private final LivingEntity entity;
/**
* The previous equipment.
*/
private final ItemStack[] slots = new ItemStack[6];
/**
* All changes between the previous equipment.
*/
private final List<Entry> changes = new LinkedList<>();
/**
* Whether the {@link #changes} have been calculated for this tick.
*/
private boolean changesCalculated;
/**
* Get the item in the inventory.
*
* <p>Slot 0 is the item in the hand.
*
* <p>Slot 1 to 4 is armor (boots to helmet).
*
* @return The item in that slot.
*/
private ItemStack getItem(int slot) {
EntityEquipment equipment = entity.getEquipment();
if (equipment == null) {
return null;
}
if (slot == 0) {
return equipment.getItemInMainHand();
} else if (slot == 1) {
return equipment.getItemInOffHand();
} else {
return equipment.getArmorContents()[slot - 2];
}
}
/**
* Update the given slot with the current value from the inventory.
*
* @param slot The slot to update.
*/
private void updateItem(int slot) {
ItemStack source = getItem(slot);
slots[slot] = source == null ? null : source.clone();
}
/**
* Check for changes in the inventory view.
*
* @return The list of changed items.
*/
public List<Entry> getChanges() {
if (!changesCalculated) {
for (int i = 0; i < 6; ++i) {
ItemStack item = getItem(i);
if (!Objects.equals(slots[i], item)) {
changes.add(new Entry(i, item));
}
}
changesCalculated = true;
}
return changes;
}
/**
* Check for changes in the armor slots.
*
* @return The list of changed items in the armor slots.
*/
public List<Entry> getArmorChanges() {
List<Entry> armor = new ArrayList<>();
for (Entry change : getChanges()) {
if (change.slot > 1) {
armor.add(change);
}
}
return armor;
}
/**
* Reset all cached changes and update latest content.
*/
public void resetChanges() {
changes.clear();
changesCalculated = false;
for (int i = 0; i < 6; i++) {
updateItem(i);
}
}
/**
* An entry which has been changed.
*/
public static class Entry {
public final int slot;
public final ItemStack item;
public Entry(int slot, ItemStack item) {
this.slot = slot;
this.item = item;
}
}
}