mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-02-27 01:32:06 +01:00
Modify items in ItemAction
This commit is contained in:
parent
8696a5709e
commit
8f538721cc
@ -51,43 +51,6 @@ public class ItemAction extends NPCShopAction {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
private boolean containsItems(ItemStack[] contents, int repeats, boolean modify) {
|
||||
List<Integer> req = items.stream().map(i -> i.getAmount() * repeats).collect(Collectors.toList());
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
ItemStack toMatch = contents[i];
|
||||
if (toMatch == null || toMatch.getType() == Material.AIR || tooDamaged(toMatch))
|
||||
continue;
|
||||
|
||||
toMatch = toMatch.clone();
|
||||
for (int j = 0; j < items.size(); j++) {
|
||||
if (toMatch == null)
|
||||
break;
|
||||
|
||||
ItemStack item = items.get(j);
|
||||
if (req.get(j) <= 0 || !matches(item, toMatch))
|
||||
continue;
|
||||
|
||||
int remaining = req.get(j);
|
||||
int taken = toMatch.getAmount() > remaining ? remaining : toMatch.getAmount();
|
||||
|
||||
if (toMatch.getAmount() == taken) {
|
||||
toMatch = null;
|
||||
} else {
|
||||
toMatch.setAmount(toMatch.getAmount() - taken);
|
||||
}
|
||||
if (modify) {
|
||||
if (toMatch == null) {
|
||||
contents[i] = null;
|
||||
} else {
|
||||
contents[i] = toMatch.clone();
|
||||
}
|
||||
}
|
||||
req.set(j, remaining - taken);
|
||||
}
|
||||
}
|
||||
return req.stream().collect(Collectors.summingInt(n -> n)) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe() {
|
||||
if (items.size() == 1)
|
||||
@ -135,6 +98,36 @@ public class ItemAction extends NPCShopAction {
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
private void giveItems(ItemStack[] inventory, int repeats) {
|
||||
for (int i = 0; i < repeats; i++) {
|
||||
List<ItemStack> toAdd = items.stream().map(ItemStack::clone).collect(Collectors.toList());
|
||||
for (int j = 0; j < inventory.length; j++) {
|
||||
if (toAdd.isEmpty())
|
||||
return;
|
||||
if (inventory[j] == null)
|
||||
continue;
|
||||
ItemStack last = toAdd.get(toAdd.size() - 1);
|
||||
if (!inventory[j].isSimilar(last) || inventory[j].getAmount() >= inventory[j].getMaxStackSize())
|
||||
continue;
|
||||
int diff = inventory[j].getMaxStackSize() - inventory[j].getAmount();
|
||||
if (diff >= last.getAmount()) {
|
||||
inventory[j].setAmount(inventory[j].getAmount() + last.getAmount());
|
||||
toAdd.remove(toAdd.size() - 1);
|
||||
} else {
|
||||
inventory[j].setAmount(inventory[j].getAmount() + diff);
|
||||
last.setAmount(last.getAmount() - diff);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < inventory.length; j++) {
|
||||
if (toAdd.isEmpty())
|
||||
break;
|
||||
if (inventory[j] == null || inventory[j].getType() == Material.AIR) {
|
||||
inventory[j] = toAdd.remove(toAdd.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction grant(Entity entity, InventoryMultiplexer im, int repeats) {
|
||||
if (!(entity instanceof InventoryHolder))
|
||||
@ -149,30 +142,8 @@ public class ItemAction extends NPCShopAction {
|
||||
}
|
||||
}
|
||||
return free >= items.size() * repeats;
|
||||
}, () -> im.transact(inventory -> {
|
||||
for (int i = 0; i < repeats; i++) {
|
||||
List<ItemStack> toAdd = items.stream().map(ItemStack::clone).collect(Collectors.toList());
|
||||
for (int j = 0; j < inventory.length; j++) {
|
||||
if (toAdd.isEmpty())
|
||||
break;
|
||||
if (inventory[j] == null || inventory[j].getType() == Material.AIR) {
|
||||
inventory[j] = toAdd.remove(toAdd.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}), () -> im.transact(inventory -> {
|
||||
for (int i = 0; i < repeats; i++) {
|
||||
List<ItemStack> toRemove = items.stream().map(ItemStack::clone).collect(Collectors.toList());
|
||||
for (int j = 0; j < inventory.length; j++) {
|
||||
if (toRemove.isEmpty())
|
||||
break;
|
||||
if (toRemove.get(toRemove.size() - 1).equals(inventory[j])) {
|
||||
inventory[j] = null;
|
||||
toRemove.remove(toRemove.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}, () -> im.transact(inventory -> giveItems(inventory, repeats)),
|
||||
() -> im.transact(inventory -> takeItems(inventory, repeats, true)));
|
||||
}
|
||||
|
||||
private boolean matches(ItemStack a, ItemStack b) {
|
||||
@ -219,29 +190,46 @@ public class ItemAction extends NPCShopAction {
|
||||
if (!(entity instanceof InventoryHolder))
|
||||
return Transaction.fail();
|
||||
|
||||
return Transaction.create(() -> containsItems(im.getInventory(), repeats, false),
|
||||
() -> im.transact(inventory -> containsItems(inventory, repeats, true)),
|
||||
() -> im.transact(inventory -> {
|
||||
for (ItemStack item : items.stream().map(ItemStack::clone).toArray(ItemStack[]::new)) {
|
||||
for (int i = 0; i < inventory.length; i++) {
|
||||
ItemStack stack = inventory[i];
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
inventory[i] = item;
|
||||
break;
|
||||
}
|
||||
if (stack.getMaxStackSize() > stack.getAmount() && matches(stack, item)) {
|
||||
int free = stack.getMaxStackSize() - stack.getAmount();
|
||||
if (item.getAmount() > free) {
|
||||
item.setAmount(item.getAmount() - free);
|
||||
stack.setAmount(stack.getMaxStackSize());
|
||||
} else {
|
||||
stack.setAmount(stack.getAmount() + item.getAmount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Transaction.create(() -> takeItems(im.getInventory(), repeats, false),
|
||||
() -> im.transact(inventory -> takeItems(inventory, repeats, true)),
|
||||
() -> im.transact(inventory -> giveItems(inventory, repeats)));
|
||||
}
|
||||
|
||||
private boolean takeItems(ItemStack[] contents, int repeats, boolean modify) {
|
||||
List<Integer> req = items.stream().map(i -> i.getAmount() * repeats).collect(Collectors.toList());
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
ItemStack toMatch = contents[i];
|
||||
if (toMatch == null || toMatch.getType() == Material.AIR || tooDamaged(toMatch))
|
||||
continue;
|
||||
|
||||
toMatch = toMatch.clone();
|
||||
for (int j = 0; j < items.size(); j++) {
|
||||
if (toMatch == null)
|
||||
break;
|
||||
|
||||
ItemStack item = items.get(j);
|
||||
if (req.get(j) <= 0 || !matches(item, toMatch))
|
||||
continue;
|
||||
|
||||
int remaining = req.get(j);
|
||||
int taken = toMatch.getAmount() > remaining ? remaining : toMatch.getAmount();
|
||||
|
||||
if (toMatch.getAmount() == taken) {
|
||||
toMatch = null;
|
||||
} else {
|
||||
toMatch.setAmount(toMatch.getAmount() - taken);
|
||||
}
|
||||
if (modify) {
|
||||
if (toMatch == null) {
|
||||
contents[i] = null;
|
||||
} else {
|
||||
contents[i] = toMatch.clone();
|
||||
}
|
||||
}));
|
||||
}
|
||||
req.set(j, remaining - taken);
|
||||
}
|
||||
}
|
||||
return req.stream().collect(Collectors.summingInt(n -> n)) <= 0;
|
||||
}
|
||||
|
||||
private boolean tooDamaged(ItemStack toMatch) {
|
||||
|
@ -375,6 +375,7 @@
|
||||
"citizens.commands.npc.sheep.color-set" : "양의 색상이 [{0}]로 설정되었습니다.",
|
||||
"citizens.commands.npc.sheep.description" : "양 타입 부여",
|
||||
"citizens.commands.npc.sheep.invalid-color" : "유효하지 않은 양 색상이 지정되었습니다. 유효한 색상은 다음과 같습니다: [[{0}]].",
|
||||
"citizens.commands.npc.shop.deleted" : "상점 [[{0}]]이(가) 삭제되었습니다.",
|
||||
"citizens.commands.npc.shop.description" : "NPC 상점 편집/표시",
|
||||
"citizens.commands.npc.shulker.color-set" : "[[{0}]]의 색상이 [{1}]로 설정되었습니다.",
|
||||
"citizens.commands.npc.shulker.description" : "셜커 타입 부여",
|
||||
|
Loading…
Reference in New Issue
Block a user