Introduce LootItem record and refactor loot handling logic to support material-specific max amounts

This commit is contained in:
akastijn 2026-07-06 00:04:53 +02:00
parent 7324177250
commit 8d05658214
4 changed files with 46 additions and 8 deletions

View File

@ -1,12 +1,16 @@
package com.alttd.hunger_games.config;
import com.alttd.hunger_games.data_objects.LootItem;
import com.alttd.hunger_games.data_objects.RARITY;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Material;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Slf4j
public class LootItems extends AbstractConfig {
static LootItems config;
@ -27,18 +31,40 @@ public class LootItems extends AbstractConfig {
public static class ITEMS {
private static final String prefix = "items.";
private static final HashMap<RARITY, List<Material>> ITEMS = new HashMap<>();
private static final HashMap<RARITY, List<LootItem>> ITEMS = new HashMap<>();
public static List<Material> get(RARITY rarity) {
public static List<LootItem> get(RARITY rarity) {
return ITEMS.get(rarity);
}
@SuppressWarnings("unused")
private static void load() {
for (RARITY rarity : RARITY.values()) {
List<String> materialNameList = ITEMS.getOrDefault(rarity, List.of()).stream().map(Material::name).toList();
List<LootItem> currentItems = ITEMS.getOrDefault(rarity, List.of());
List<String> materialNameList = currentItems.stream()
.map(item -> item.material().name() + (item.maxAmount() > 1 ? ":" + item.maxAmount() : ""))
.toList();
List<String> materialList = config.getList(prefix, rarity.getConfigName(), materialNameList);
ITEMS.put(rarity, materialList.stream().map(Material::getMaterial).toList());
List<LootItem> lootItems = new ArrayList<>();
for (String entry : materialList) {
String[] split = entry.split(":");
Material material = Material.getMaterial(split[0].toUpperCase());
if (material == null) {
log.warn("Invalid material found in loot-items.yml: {}", split[0]);
continue;
}
int maxAmount = 1;
if (split.length > 1) {
try {
maxAmount = Integer.parseInt(split[1]);
} catch (NumberFormatException ignored) {
log.error("Invalid max amount found in loot-items.yml: {}", split[1]);
}
}
lootItems.add(new LootItem(material, maxAmount));
}
ITEMS.put(rarity, lootItems);
}
}
}

View File

@ -0,0 +1,6 @@
package com.alttd.hunger_games.data_objects;
import org.bukkit.Material;
public record LootItem(Material material, int maxAmount) {
}

View File

@ -1,6 +1,7 @@
package com.alttd.hunger_games.services;
import com.alttd.hunger_games.config.LootItems;
import com.alttd.hunger_games.data_objects.LootItem;
import com.alttd.hunger_games.data_objects.RARITY;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.Component;
@ -38,15 +39,20 @@ public class LootService {
for (int i = 0; i < itemCount; i++) {
int slot = random.nextInt(27);
RARITY rarity = decideRarity();
List<Material> possibleItems = LootItems.ITEMS.get(rarity);
List<LootItem> possibleItems = LootItems.ITEMS.get(rarity);
if (possibleItems == null || possibleItems.isEmpty()) {
log.warn("No items found for rarity: {}", rarity);
continue;
}
Material material = possibleItems.get(random.nextInt(possibleItems.size()));
inventory.setItem(slot, new ItemStack(material));
LootItem lootItem = possibleItems.get(random.nextInt(possibleItems.size()));
if (lootItem == null || lootItem.material() == null) {
log.warn("LootItem or material is null for rarity: {}", rarity);
continue;
}
int amount = lootItem.maxAmount() > 1 ? random.nextInt(lootItem.maxAmount()) + 1 : 1;
inventory.setItem(slot, new ItemStack(lootItem.material(), amount));
}
return inventory;

View File

@ -91,7 +91,7 @@ public class Round {
startCountdown(Config.ROUND.SAFE_PHASE, () -> {
nextStage(); // SAFE_PHASE -> KILL_PHASE
GameStageHandler.broadcastMessage(Messages.GAME.NEXT_STATE.replace("<round>", roundState.getHumanReadableName()));
startCountdown(Config.ROUND.KILL_PHASE, () -> scheduleNextStage(0));
scheduleNextStage(0);
});
});
}