mirror of
https://github.com/filoghost/ChestCommands.git
synced 2025-02-19 21:11:42 +01:00
Refactor and fix multiple required items
This commit is contained in:
parent
134e996c6c
commit
4a5c06398f
@ -20,11 +20,11 @@ import me.filoghost.chestcommands.action.OpenMenuAction;
|
||||
import me.filoghost.chestcommands.api.ClickResult;
|
||||
import me.filoghost.chestcommands.api.MenuInventory;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredExpLevel;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredItem;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredItems;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredMoney;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredPermission;
|
||||
import me.filoghost.chestcommands.icon.requirement.Requirement;
|
||||
import me.filoghost.chestcommands.icon.requirement.item.RequiredItem;
|
||||
import me.filoghost.chestcommands.icon.requirement.item.RequiredItems;
|
||||
import me.filoghost.chestcommands.util.Preconditions;
|
||||
import me.filoghost.chestcommands.util.collection.CollectionUtils;
|
||||
import org.bukkit.Material;
|
||||
|
@ -0,0 +1,79 @@
|
||||
package me.filoghost.chestcommands.icon.requirement.item;
|
||||
|
||||
import me.filoghost.chestcommands.util.MaterialsHelper;
|
||||
import me.filoghost.chestcommands.util.Preconditions;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class InventoryTakeHelper {
|
||||
|
||||
private final PlayerInventory inventory;
|
||||
private final List<RemainingItem> remainingItems;
|
||||
|
||||
private boolean success;
|
||||
|
||||
public InventoryTakeHelper(PlayerInventory inventory) {
|
||||
this.inventory = inventory;
|
||||
this.remainingItems = new ArrayList<>();
|
||||
|
||||
for (int slotIndex = 0; slotIndex < inventory.getSize(); slotIndex++) {
|
||||
ItemStack item = inventory.getItem(slotIndex);
|
||||
if (item != null && !MaterialsHelper.isAir(item.getType())) {
|
||||
remainingItems.add(new RemainingItem(slotIndex, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<RequiredItem> prepareTakeItems(List<RequiredItem> requiredItems) {
|
||||
List<RequiredItem> missingItems = new ArrayList<>();
|
||||
|
||||
// Sort required items: check required items with a restrictive durability first
|
||||
List<RequiredItem> sortedRequiredItems = requiredItems.stream()
|
||||
.sorted(Comparator.comparing(RequiredItem::hasRestrictiveDurability).reversed())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (RequiredItem requiredItem : sortedRequiredItems) {
|
||||
int remainingRequiredAmount = requiredItem.getAmount();
|
||||
|
||||
for (RemainingItem remainingItem : remainingItems) {
|
||||
if (remainingItem.getAmount() > 0 && requiredItem.isMatchingType(remainingItem)) {
|
||||
int takenAmount = remainingItem.subtract(remainingRequiredAmount);
|
||||
remainingRequiredAmount -= takenAmount;
|
||||
if (remainingRequiredAmount == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't take the required amount of an item
|
||||
if (remainingRequiredAmount > 0) {
|
||||
missingItems.add(requiredItem);
|
||||
}
|
||||
}
|
||||
|
||||
success = missingItems.isEmpty();
|
||||
return missingItems;
|
||||
}
|
||||
|
||||
public void applyTakeItems() {
|
||||
Preconditions.checkState(success, "items take preparation was not run or successful");
|
||||
|
||||
for (RemainingItem remainingItem : remainingItems) {
|
||||
int slotIndex = remainingItem.getSlotIndex();
|
||||
ItemStack inventoryItem = inventory.getItem(slotIndex);
|
||||
if (remainingItem.getAmount() != inventoryItem.getAmount()) {
|
||||
if (remainingItem.getAmount() > 0) {
|
||||
inventoryItem.setAmount(remainingItem.getAmount());
|
||||
} else {
|
||||
inventory.setItem(slotIndex, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package me.filoghost.chestcommands.icon.requirement.item;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class RemainingItem {
|
||||
|
||||
private final int slotIndex;
|
||||
private final Material material;
|
||||
private final short durability;
|
||||
private int amount;
|
||||
|
||||
public RemainingItem(int slotIndex, ItemStack item) {
|
||||
this.slotIndex = slotIndex;
|
||||
this.material = item.getType();
|
||||
this.durability = item.getDurability();
|
||||
this.amount = item.getAmount();
|
||||
}
|
||||
|
||||
public int getSlotIndex() {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public short getDurability() {
|
||||
return durability;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int subtract(int minusAmount) {
|
||||
int subtractedAmount = Math.min(minusAmount, this.amount);
|
||||
|
||||
this.amount -= subtractedAmount;
|
||||
return subtractedAmount;
|
||||
}
|
||||
|
||||
}
|
@ -12,12 +12,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package me.filoghost.chestcommands.icon.requirement;
|
||||
package me.filoghost.chestcommands.icon.requirement.item;
|
||||
|
||||
import me.filoghost.chestcommands.util.Preconditions;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class RequiredItem {
|
||||
|
||||
@ -56,55 +54,16 @@ public class RequiredItem {
|
||||
return isDurabilityRestrictive;
|
||||
}
|
||||
|
||||
public boolean isItemContainedIn(Inventory inventory) {
|
||||
int amountFound = 0;
|
||||
|
||||
for (ItemStack item : inventory.getContents()) {
|
||||
if (isMatchingType(item)) {
|
||||
amountFound += item.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
return amountFound >= amount;
|
||||
}
|
||||
|
||||
public boolean takeItemFrom(Inventory inventory) {
|
||||
if (amount <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int itemsToTake = amount; // Start from amount and decrease
|
||||
ItemStack[] contents = inventory.getContents();
|
||||
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
ItemStack current = contents[i];
|
||||
|
||||
if (isMatchingType(current)) {
|
||||
if (current.getAmount() > itemsToTake) {
|
||||
current.setAmount(current.getAmount() - itemsToTake);
|
||||
return true;
|
||||
} else {
|
||||
itemsToTake -= current.getAmount();
|
||||
inventory.setItem(i, new ItemStack(Material.AIR));
|
||||
}
|
||||
}
|
||||
|
||||
// The end
|
||||
if (itemsToTake <= 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isMatchingType(ItemStack item) {
|
||||
return item != null && item.getType() == material && isMatchingDurability(item.getDurability());
|
||||
public boolean isMatchingType(RemainingItem item) {
|
||||
return item != null && item.getMaterial() == material && isMatchingDurability(item.getDurability());
|
||||
}
|
||||
|
||||
private boolean isMatchingDurability(short durability) {
|
||||
if (!isDurabilityRestrictive) {
|
||||
if (isDurabilityRestrictive) {
|
||||
return this.durability == durability;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return this.durability == durability;
|
||||
}
|
||||
|
||||
}
|
@ -12,10 +12,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package me.filoghost.chestcommands.icon.requirement;
|
||||
package me.filoghost.chestcommands.icon.requirement.item;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.filoghost.chestcommands.ChestCommands;
|
||||
import me.filoghost.chestcommands.icon.requirement.Requirement;
|
||||
import me.filoghost.chestcommands.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -31,34 +32,31 @@ public class RequiredItems implements Requirement {
|
||||
|
||||
@Override
|
||||
public boolean hasCost(Player player) {
|
||||
boolean missingItems = false;
|
||||
|
||||
for (RequiredItem item : items) {
|
||||
if (!item.isItemContainedIn(player.getInventory())) {
|
||||
missingItems = true;
|
||||
player.sendMessage(ChestCommands.getLang().no_required_item
|
||||
.replace("{material}", Utils.formatEnum(item.getMaterial()))
|
||||
.replace("{amount}", Integer.toString(item.getAmount()))
|
||||
.replace("{durability}", item.hasRestrictiveDurability() ? Short.toString(item.getDurability()) : ChestCommands.getLang().any)
|
||||
);
|
||||
}
|
||||
InventoryTakeHelper inventoryTakeHelper = new InventoryTakeHelper(player.getInventory());
|
||||
List<RequiredItem> missingItems = inventoryTakeHelper.prepareTakeItems(items);
|
||||
|
||||
for (RequiredItem item : missingItems) {
|
||||
player.sendMessage(ChestCommands.getLang().no_required_item
|
||||
.replace("{material}", Utils.formatEnum(item.getMaterial()))
|
||||
.replace("{amount}", Integer.toString(item.getAmount()))
|
||||
.replace("{durability}", item.hasRestrictiveDurability() ? Short.toString(item.getDurability()) : ChestCommands.getLang().any)
|
||||
);
|
||||
}
|
||||
|
||||
return !missingItems;
|
||||
return missingItems.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeCost(Player player) {
|
||||
boolean missingItems = false;
|
||||
|
||||
for (RequiredItem item : items) {
|
||||
boolean success = item.takeItemFrom(player.getInventory());
|
||||
if (!success) {
|
||||
missingItems = true;
|
||||
}
|
||||
InventoryTakeHelper inventoryTakeHelper = new InventoryTakeHelper(player.getInventory());
|
||||
List<RequiredItem> missingItems = inventoryTakeHelper.prepareTakeItems(items);
|
||||
|
||||
if (!missingItems.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !missingItems;
|
||||
inventoryTakeHelper.applyTakeItems();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
package me.filoghost.chestcommands.parsing.attribute;
|
||||
|
||||
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
|
||||
import me.filoghost.chestcommands.icon.requirement.RequiredItem;
|
||||
import me.filoghost.chestcommands.icon.requirement.item.RequiredItem;
|
||||
import me.filoghost.chestcommands.parsing.ItemStackParser;
|
||||
import me.filoghost.chestcommands.parsing.ParseException;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user