Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>2.26.0</build.version>
<build.version>2.27.0</build.version>
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
Expand Down
127 changes: 118 additions & 9 deletions src/main/java/world/bentobox/level/commands/IslandDonateCommand.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package world.bentobox.level.commands;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;

import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
Expand All @@ -17,13 +20,17 @@
import world.bentobox.level.util.Utils;

/**
* Command: /island donate [hand [amount]]
* Opens a donation GUI or donates blocks from hand.
* Command: /island donate [hand [amount]] [inv]
* Opens a donation GUI, or donates blocks from the player's hand, or
* donates every donatable block from the player's inventory.
*
* @author tastybento
*/
public class IslandDonateCommand extends ConfirmableCommand {

private static final String MATERIAL_PLACEHOLDER = "[material]";
private static final String POINTS_PLACEHOLDER = "[points]";

private final Level addon;

public IslandDonateCommand(Level addon, CompositeCommand parent) {
Expand Down Expand Up @@ -65,6 +72,11 @@ public boolean execute(User user, String label, List<String> args) {
return handleHandDonation(user, island, args);
}

// Handle "inv" subcommand (accepts English "inv" or the localized keyword)
if (!args.isEmpty() && isInvKeyword(user, args.get(0))) {
return handleInvDonation(user, island);
}

// No args - open GUI
DonationPanel.openPanel(addon, getWorld(), user, island);
return true;
Expand Down Expand Up @@ -111,8 +123,8 @@ private boolean handleHandDonation(User user, Island island, List<String> args)

String prompt = user.getTranslation("island.donate.hand.confirm-prompt",
TextVariables.NUMBER, String.valueOf(previewAmount),
"[material]", Utils.prettifyObject(material, user),
"[points]", Utils.formatNumber(user, previewPoints));
MATERIAL_PLACEHOLDER, Utils.prettifyObject(material, user),
POINTS_PLACEHOLDER, Utils.formatNumber(user, previewPoints));

askConfirmation(user, prompt, () -> performHandDonation(user, island, material, blockValue, finalRequested));
return true;
Expand All @@ -138,18 +150,110 @@ private void performHandDonation(User user, Island island, Material material, in

user.sendMessage("island.donate.hand.success",
TextVariables.NUMBER, String.valueOf(amount),
"[material]", Utils.prettifyObject(material, user),
"[points]", Utils.formatNumber(user, points));
MATERIAL_PLACEHOLDER, Utils.prettifyObject(material, user),
POINTS_PLACEHOLDER, Utils.formatNumber(user, points));
}

/**
* Handle the /island donate inv subcommand. Scans the player's inventory for
* blocks with a positive donation value, shows a per-material breakdown plus
* the total, and asks for confirmation. Items with no value or that aren't
* donatable blocks remain in the inventory.
*/
private boolean handleInvDonation(User user, Island island) {
Map<Material, Integer> totals = collectDonatableTotals(user.getPlayer().getInventory());

if (totals.isEmpty()) {
user.sendMessage("island.donate.empty");
return false;
}

long totalPoints = 0L;
StringBuilder prompt = new StringBuilder(
user.getTranslation("island.donate.inv.confirm-header"));
for (Map.Entry<Material, Integer> e : totals.entrySet()) {
int value = addon.getBlockConfig().getValue(getWorld(), e.getKey());
long points = (long) value * e.getValue();
totalPoints += points;
prompt.append('\n').append(user.getTranslation("island.donate.inv.confirm-line",
TextVariables.NUMBER, String.valueOf(e.getValue()),
MATERIAL_PLACEHOLDER, Utils.prettifyObject(e.getKey(), user),
POINTS_PLACEHOLDER, Utils.formatNumber(user, points)));
}
prompt.append('\n').append(user.getTranslation("island.donate.inv.confirm-total",
POINTS_PLACEHOLDER, Utils.formatNumber(user, totalPoints)));

askConfirmation(user, prompt.toString(), () -> performInvDonation(user, island));
return true;
}

private void performInvDonation(User user, Island island) {
PlayerInventory pInv = user.getPlayer().getInventory();
ItemStack[] contents = pInv.getStorageContents();
Map<Material, Integer> donated = new EnumMap<>(Material.class);
long totalPoints = 0L;

for (int i = 0; i < contents.length; i++) {
ItemStack item = contents[i];
Integer value = donationValue(item);
if (value == null) {
continue;
}
int amount = item.getAmount();
long points = (long) value * amount;
donated.merge(item.getType(), amount, Integer::sum);
totalPoints += points;
addon.getManager().donateBlocks(island, user.getUniqueId(), item.getType().name(), amount, points);
contents[i] = null;
}
pInv.setStorageContents(contents);

if (donated.isEmpty()) {
user.sendMessage("island.donate.empty");
return;
}
int totalBlocks = donated.values().stream().mapToInt(Integer::intValue).sum();
user.sendMessage("island.donate.success",
POINTS_PLACEHOLDER, Utils.formatNumber(user, totalPoints),
TextVariables.NUMBER, String.valueOf(totalBlocks));
addon.getManager().recalculateAfterDonation(island);
}

private Map<Material, Integer> collectDonatableTotals(PlayerInventory pInv) {
Map<Material, Integer> totals = new EnumMap<>(Material.class);
for (ItemStack item : pInv.getStorageContents()) {
if (donationValue(item) != null) {
totals.merge(item.getType(), item.getAmount(), Integer::sum);
}
}
return totals;
}

/**
* @return the per-block donation value if the item is a donatable block with a
* positive configured value, or null otherwise
*/
private Integer donationValue(ItemStack item) {
if (item == null || item.getType().isAir() || !item.getType().isBlock()) {
return null;
}
Integer value = addon.getBlockConfig().getValue(getWorld(), item.getType());
return (value != null && value > 0) ? value : null;
}

@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
// BentoBox includes the command label as args.get(0); the user-typed args start at index 1.
String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : "";
String handKeyword = user.getTranslation("island.donate.hand.keyword");
if (args.size() <= 1) {
return Optional.of(Util.tabLimit(List.of(handKeyword), lastArg));
String invKeyword = user.getTranslation("island.donate.inv.keyword");

// First user-arg slot: suggest "hand" and "inv".
if (args.size() <= 2) {
return Optional.of(Util.tabLimit(List.of(handKeyword, invKeyword), lastArg));
}
if (args.size() == 2 && isHandKeyword(user, args.get(0)) && user.isPlayer()) {
// Second user-arg slot after "hand": suggest the held count.
if (args.size() == 3 && isHandKeyword(user, args.get(1)) && user.isPlayer()) {
int held = user.getPlayer().getInventory().getItemInMainHand().getAmount();
if (held > 0) {
return Optional.of(Util.tabLimit(List.of(String.valueOf(held)), lastArg));
Expand All @@ -162,4 +266,9 @@ private boolean isHandKeyword(User user, String arg) {
String localized = user.getTranslation("island.donate.hand.keyword");
return "hand".equalsIgnoreCase(arg) || localized.equalsIgnoreCase(arg);
}

private boolean isInvKeyword(User user, String arg) {
String localized = user.getTranslation("island.donate.inv.keyword");
return "inv".equalsIgnoreCase(arg) || localized.equalsIgnoreCase(arg);
}
}
5 changes: 5 additions & 0 deletions src/main/resources/locales/cs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Tyto bloky budou ZNIČENY z tvého inventáře:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> bodů"
confirm-total: "<red>Celkem: <aqua>[points]<red> trvalých bodů."
detail:
description: "zobrazit podrobnosti o blocích vašeho ostrova"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Diese Blöcke werden aus deinem Inventar ZERSTÖRT:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> Punkte"
confirm-total: "<red>Gesamt: <aqua>[points]<red> permanente Punkte."
detail:
description: "zeigt Details der Blöcke deiner Insel"
top:
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ island:
in-progress: "<gold>Island level calculation is in progress..."
time-out: "<red>The level calculation took too long. Please try again later."
donate:
parameters: "[hand [amount]]"
parameters: "[hand [amount]] [inv]"
description: "donate blocks to permanently raise island level"
must-be-on-island: "<red>You must be on your island to donate blocks."
no-permission: "<red>You do not have permission to donate blocks on this island."
Expand All @@ -72,6 +72,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>About to DESTROY these blocks from your inventory:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> points"
confirm-total: "<red>Total: <aqua>[points]<red> permanent points."
detail:
description: "shows detail of your island blocks"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Estos bloques serán DESTRUIDOS de tu inventario:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> puntos"
confirm-total: "<red>Total: <aqua>[points]<red> puntos permanentes."
detail:
description: "muestra el detalle de los bloques de tu isla"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Ces blocs vont être DÉTRUITS de votre inventaire :"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> points"
confirm-total: "<red>Total : <aqua>[points]<red> points permanents."
top:
description: affiche le top 10
gui-title: "<green>Top 10"
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/hu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Ezeket a blokkokat MEGSEMMISÍTI a leltáradból:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> pont"
confirm-total: "<red>Összesen: <aqua>[points]<red> állandó pont."
detail:
description: "megmutatja a szigeted blokkjainak részleteit"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/id.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Akan MENGHANCURKAN blok-blok ini dari inventaris Anda:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> poin"
confirm-total: "<red>Total: <aqua>[points]<red> poin permanen."
top:
description: menunjukkan Sepuluh Besar
gui-title: "<green> Sepuluh Besar"
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>인벤토리에서 다음 블록을 파괴합니다:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> 점"
confirm-total: "<red>총: <aqua>[points]<red> 영구 점수."
detail:
description: "섬 블록의 세부 정보를 표시합니다"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/lv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Šie bloki tiks IZNĪCINĀTI no tavas somas:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> punkti"
confirm-total: "<red>Kopā: <aqua>[points]<red> pastāvīgi punkti."
detail:
description: "rāda tavas salas bloku detaļas"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Deze blokken worden VERNIETIGD uit je inventaris:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> punten"
confirm-total: "<red>Totaal: <aqua>[points]<red> permanente punten."
top:
description: Toon de Top tien
gui-title: "<green> Top tien"
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/pl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Te bloki zostaną ZNISZCZONE z twojego ekwipunku:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> punktów"
confirm-total: "<red>Łącznie: <aqua>[points]<red> punktów stałych."
top:
description: pokauje Top 10 wysp
gui-title: "<green>Top 10"
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/pt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Estes blocos serão DESTRUÍDOS do seu inventário:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> pontos"
confirm-total: "<red>Total: <aqua>[points]<red> pontos permanentes."
detail:
description: "mostra os detalhes dos blocos da sua ilha"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Эти блоки будут УНИЧТОЖЕНЫ из вашего инвентаря:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> очков"
confirm-total: "<red>Всего: <aqua>[points]<red> постоянных очков."
detail:
description: показать информацию о блоках на вашем острове
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/tr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ island:
success: "<green>Donated [number] x [material] for <aqua>[points]<green> permanent points!"
not-block: "<red>You must be holding a placeable block to donate."
confirm-prompt: "<red>About to DESTROY <gold>[number] x [material]<red> for <aqua>[points]<red> permanent points."
inv:
keyword: "inv"
confirm-header: "<red>Envanterinizden bu bloklar YOK EDİLECEK:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> puan"
confirm-total: "<red>Toplam: <aqua>[points]<red> kalıcı puan."
detail:
description: "adanın blok ayrıntılarını gösterir"
top:
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/locales/uk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ island:
success: "<green>Пожертвовано [number] x [material] за <aqua>[points]<green> постійних очок!"
not-block: "<red>Ви повинні тримати блок, який можна розмістити."
confirm-prompt: "<red>Буде ЗНИЩЕНО <gold>[number] x [material]<red> за <aqua>[points]<red> постійних очок."
inv:
keyword: "inv"
confirm-header: "<red>Ці блоки будуть ЗНИЩЕНІ з вашого інвентарю:"
confirm-line: "<gold>[number] x [material] <gray>= <aqua>[points]<gray> очок"
confirm-total: "<red>Всього: <aqua>[points]<red> постійних очок."
top:
description: показати першу десятку
gui-title: "& Десятка Кращих"
Expand Down
Loading
Loading