Skip to content

Commit

Permalink
Add requireUndamaged to item cost
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Oct 26, 2022
1 parent a91f0cd commit 891b480
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 34 deletions.
25 changes: 14 additions & 11 deletions main/src/main/java/net/citizensnpcs/trait/ShopTrait.java
Expand Up @@ -156,12 +156,19 @@ public NPCShopContentsEditor(NPCShop shop) {

public void changePage(int newPage) {
this.page = newPage;
NPCShopPage sp = shop.getOrCreatePage(page);
NPCShopPage shopPage = shop.getOrCreatePage(page);
for (int i = 0; i < ctx.getInventory().getSize(); i++) {
ctx.getSlot(i).clear();
NPCShopItem item = sp.getItem(i);
InventoryMenuSlot slot = ctx.getSlot(i);
slot.clear();
NPCShopItem item = shopPage.getItem(i);

if (item != null) {
slot.setItemStack(item.display);
}

final int idx = i;
ctx.getSlot(i).setClickHandler(evt -> {
slot.setClickHandler(evt -> {
evt.setCancelled(true);
ctx.clearSlots();
NPCShopItem display = item;
if (display == null) {
Expand All @@ -173,18 +180,14 @@ public void changePage(int newPage) {

ctx.getMenu().transition(new NPCShopItemEditor(display, modified -> {
if (modified == null) {
sp.removeItem(idx);
shopPage.removeItem(idx);
} else {
sp.setItem(idx, modified);
shopPage.setItem(idx, modified);
}
}));
});

if (item == null)
continue;

ctx.getSlot(i).setItemStack(item.display);
}

InventoryMenuSlot prev = ctx.getSlot(4 * 9 + 3);
InventoryMenuSlot edit = ctx.getSlot(4 * 9 + 4);
InventoryMenuSlot next = ctx.getSlot(4 * 9 + 5);
Expand Down
66 changes: 43 additions & 23 deletions main/src/main/java/net/citizensnpcs/trait/shop/ItemAction.java
Expand Up @@ -3,18 +3,22 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;

import com.google.common.collect.Lists;

import net.citizensnpcs.api.gui.BooleanSlotHandler;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.InventoryMenuSlot;
import net.citizensnpcs.api.gui.Menu;
Expand All @@ -25,6 +29,8 @@
public class ItemAction extends NPCShopAction {
@Persist
public List<ItemStack> items = Lists.newArrayList();
@Persist
public boolean requireUndamaged = true;

public ItemAction() {
}
Expand All @@ -37,6 +43,32 @@ public ItemAction(List<ItemStack> items) {
this.items = items;
}

private boolean containsItems(Inventory source, BiFunction<ItemStack, Integer, ItemStack> filter) {
Map<Material, Integer> required = items.stream()
.collect(Collectors.toMap(k -> k.getType(), v -> v.getAmount()));
ItemStack[] contents = source.getContents();
for (int i = 0; i < contents.length; i++) {
ItemStack stack = contents[i];
if (stack == null || stack.getType() == Material.AIR || !required.containsKey(stack.getType()))
continue;
if (requireUndamaged && stack.getItemMeta() instanceof Damageable
&& ((Damageable) stack.getItemMeta()).getDamage() != 0)
continue;
int remaining = required.remove(stack.getType());
int taken = stack.getAmount() > remaining ? remaining : stack.getAmount();
ItemStack res = filter.apply(stack, taken);
if (res == null) {
source.clear(i);
} else {
source.setItem(i, res);
}
if (remaining - taken > 0) {
required.put(stack.getType(), remaining - taken);
}
}
return required.size() == 0;
}

@Override
public Transaction grant(Entity entity) {
if (!(entity instanceof InventoryHolder))
Expand Down Expand Up @@ -64,45 +96,28 @@ public Transaction take(Entity entity) {
return Transaction.fail();
Inventory source = ((InventoryHolder) entity).getInventory();
return Transaction.create(() -> {
Map<Material, Integer> required = items.stream()
.collect(Collectors.toMap(k -> k.getType(), v -> v.getAmount()));
boolean contains = true;
for (Map.Entry<Material, Integer> entry : required.entrySet()) {
contains &= source.contains(entry.getKey(), entry.getValue());
}
boolean contains = containsItems(source, (s, t) -> s);
for (ItemStack item : items) {
if (item.hasItemMeta() && !source.contains(item)) {
contains = false;
}
}
return contains;
}, () -> {
Map<Material, Integer> required = items.stream()
.collect(Collectors.toMap(k -> k.getType(), v -> v.getAmount()));
ItemStack[] contents = source.getContents();
for (int i = 0; i < contents.length; i++) {
ItemStack stack = contents[i];
if (stack == null || stack.getType() == Material.AIR || !required.containsKey(stack.getType()))
continue;
Material type = stack.getType();
int remaining = required.remove(type);
int taken = stack.getAmount() > remaining ? remaining : stack.getAmount();
containsItems(source, (stack, taken) -> {
if (stack.getAmount() == taken) {
source.clear(i);
return null;
} else {
stack.setAmount(stack.getAmount() - taken);
source.setItem(i, stack);
return stack;
}
if (remaining - taken > 0) {
required.put(type, remaining - taken);
}
}
});
}, () -> {
source.addItem(items.toArray(new ItemStack[items.size()]));
});
}

@Menu(title = "Item editor", dimensions = { 3, 9 })
@Menu(title = "Item editor", dimensions = { 4, 9 })
public static class ItemActionEditor extends InventoryMenuPage {
private ItemAction base;
private Consumer<NPCShopAction> callback;
Expand Down Expand Up @@ -130,6 +145,11 @@ public void initialise(MenuContext ctx) {
event.setCurrentItem(event.getCursorNonNull());
});
}
ctx.getSlot(3 * 9 + 1).setItemStack(new ItemStack(Material.ANVIL), "Must have no damage");
ctx.getSlot(3 * 9 + 1).addClickHandler(new BooleanSlotHandler((res) -> {
base.requireUndamaged = res;
return res ? ChatColor.GREEN + "On" : ChatColor.RED + "Off";
}, base == null ? false : base.requireUndamaged));
}

@Override
Expand Down

0 comments on commit 891b480

Please sign in to comment.