Compare commits
4 Commits
a137ef4cc6
...
8d05658214
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d05658214 | ||
|
|
7324177250 | ||
|
|
c7161f707c | ||
|
|
5ce26782f2 |
|
|
@ -4,11 +4,7 @@ import com.alttd.hunger_games.commands.BaseCommand;
|
|||
import com.alttd.hunger_games.config.Config;
|
||||
import com.alttd.hunger_games.config.LootItems;
|
||||
import com.alttd.hunger_games.config.Messages;
|
||||
import com.alttd.hunger_games.event_listeners.ChestListener;
|
||||
import com.alttd.hunger_games.event_listeners.ItemSpawnListener;
|
||||
import com.alttd.hunger_games.event_listeners.PlayerDamageListener;
|
||||
import com.alttd.hunger_games.event_listeners.PlayerDisconnectListener;
|
||||
import com.alttd.hunger_games.event_listeners.PlayerJoinListener;
|
||||
import com.alttd.hunger_games.event_listeners.*;
|
||||
import com.alttd.hunger_games.services.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
|
@ -64,6 +60,7 @@ public final class Main extends JavaPlugin {
|
|||
pluginManager.registerEvents(new PlayerDamageListener(roundService, playerService, statService), this);
|
||||
pluginManager.registerEvents(new ChestListener(roundService, lootService), this);
|
||||
pluginManager.registerEvents(new ItemSpawnListener(roundService), this);
|
||||
pluginManager.registerEvents(new CommandListener(), this);
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class NextPhase extends SubCommand {
|
|||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
round.forceNextPhase();
|
||||
commandSender.sendRichMessage("<green>Skipping to the next phase/stage.</green>");
|
||||
commandSender.sendRichMessage(Messages.COMMANDS.NEXT_PHASE_SUCCESS);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class Config extends AbstractConfig {
|
||||
|
|
@ -45,6 +42,8 @@ public class Config extends AbstractConfig {
|
|||
private static final String prefix = "round.";
|
||||
|
||||
public static Duration COUNTDOWN = Duration.ofSeconds(10);
|
||||
public static Duration SAFE_PHASE = Duration.ofSeconds(30);
|
||||
public static Duration KILL_PHASE = Duration.ofMinutes(5);
|
||||
public static int INITIAL_BORDER_SIZE = 5000;
|
||||
public static List<GameStage> STAGES = List.of(
|
||||
GameStage.builder().duration(Duration.ofMinutes(5)).worldBorderSize(1000).build(),
|
||||
|
|
@ -56,6 +55,10 @@ public class Config extends AbstractConfig {
|
|||
private static void load() {
|
||||
int countdownSeconds = config.getInt(prefix, "countdown-seconds", Math.toIntExact(COUNTDOWN.toSeconds()));
|
||||
COUNTDOWN = Duration.ofSeconds(countdownSeconds);
|
||||
int safePhaseSeconds = config.getInt(prefix, "safe-phase-seconds", Math.toIntExact(SAFE_PHASE.toSeconds()));
|
||||
SAFE_PHASE = Duration.ofSeconds(safePhaseSeconds);
|
||||
int killPhaseSeconds = config.getInt(prefix, "kill-phase-seconds", Math.toIntExact(KILL_PHASE.toSeconds()));
|
||||
KILL_PHASE = Duration.ofSeconds(killPhaseSeconds);
|
||||
INITIAL_BORDER_SIZE = config.getInt(prefix, "initial-border-size", INITIAL_BORDER_SIZE);
|
||||
|
||||
ConfigurationSection configurationSection = config.getConfigurationSection(prefix + "stages");
|
||||
|
|
@ -134,4 +137,17 @@ public class Config extends AbstractConfig {
|
|||
STUCK_WARMUP = Duration.ofSeconds(config.getInt(prefix, "stuck-warmup-seconds", (int) STUCK_WARMUP.toSeconds()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class COMMAND_WHITELIST {
|
||||
private static final String prefix = "command-whitelist";
|
||||
|
||||
public static final List<String> PREFIXES = new ArrayList<>(List.of("msg", "ac", "gac", "tell", "r", "server", "lobby", "hub", "bayou", "creative", "hg", "lp"));
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
List<String> stringList = config.getStringList(prefix, "prefix-list", PREFIXES);
|
||||
PREFIXES.clear();
|
||||
PREFIXES.addAll(stringList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public class Messages extends AbstractConfig {
|
|||
public static String PLAYER_ONLY = "<red>This command can only be executed as a player</red>";
|
||||
public static String PLAYER_NOT_FOUND = "<red>Unable to find online player <player></red>";
|
||||
public static String RELOAD_SUCCESS = "<green>Config and messages have been reloaded.</green>";
|
||||
public static String COMMAND_BLOCKED = "<red>You cannot use that command here!</red>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
|
|
@ -64,6 +65,7 @@ public class Messages extends AbstractConfig {
|
|||
PLAYER_ONLY = config.getString(prefix, "player-only", PLAYER_ONLY);
|
||||
PLAYER_NOT_FOUND = config.getString(prefix, "player-only", PLAYER_NOT_FOUND);
|
||||
RELOAD_SUCCESS = config.getString(prefix, "reload-success", RELOAD_SUCCESS);
|
||||
COMMAND_BLOCKED = config.getString(prefix, "command-blocked", COMMAND_BLOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +91,7 @@ public class Messages extends AbstractConfig {
|
|||
public static String PLAYER_DEATH = "<red><player> has died! <gold><remaining></gold> players remaining.</red>";
|
||||
|
||||
public static String BOSSBAR_COUNTDOWN = "<gold>Loot phase in <time></gold>";
|
||||
public static String BOSSBAR_PVP_COUNTDOWN = "<green>PVP starts in <time></green>";
|
||||
public static String BOSSBAR_SAFE_PHASE = "<green>Border shrinking in <time></green>";
|
||||
public static String BOSSBAR_KILL_PHASE = "<red>Border shrinking... <time></red>";
|
||||
public static String BOSSBAR_FINALE = "<gold>Remaining Players: <remaining></gold>";
|
||||
|
|
@ -105,6 +108,7 @@ public class Messages extends AbstractConfig {
|
|||
PLAYER_DEATH = config.getString(prefix, "player-death", PLAYER_DEATH);
|
||||
|
||||
BOSSBAR_COUNTDOWN = config.getString(prefix, "bossbar-countdown", BOSSBAR_COUNTDOWN);
|
||||
BOSSBAR_PVP_COUNTDOWN = config.getString(prefix, "bossbar-pvp-countdown", BOSSBAR_PVP_COUNTDOWN);
|
||||
BOSSBAR_SAFE_PHASE = config.getString(prefix, "bossbar-border-shrinking-in", BOSSBAR_SAFE_PHASE);
|
||||
BOSSBAR_KILL_PHASE = config.getString(prefix, "bossbar-border-shrinking", BOSSBAR_KILL_PHASE);
|
||||
BOSSBAR_FINALE = config.getString(prefix, "bossbar-finale", BOSSBAR_FINALE);
|
||||
|
|
@ -199,4 +203,15 @@ public class Messages extends AbstractConfig {
|
|||
STATS_FORMAT = config.getString(prefix, "format", STATS_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
public static class COMMANDS {
|
||||
private static final String prefix = "commands.";
|
||||
|
||||
public static String NEXT_PHASE_SUCCESS = "<green>Skipping to the next phase/stage.</green>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
NEXT_PHASE_SUCCESS = config.getString(prefix + "next-phase", "success", NEXT_PHASE_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package com.alttd.hunger_games.data_objects;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public record LootItem(Material material, int maxAmount) {
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.alttd.hunger_games.event_listeners;
|
||||
|
||||
import com.alttd.hunger_games.config.Config;
|
||||
import com.alttd.hunger_games.config.Messages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class CommandListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("hg.bypass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove leading slash
|
||||
String message = event.getMessage().substring(1).toLowerCase();
|
||||
String command = message.split(" ")[0];
|
||||
|
||||
boolean whitelisted = Config.COMMAND_WHITELIST.PREFIXES.stream()
|
||||
.anyMatch(prefix -> command.startsWith(prefix.toLowerCase()));
|
||||
|
||||
if (!whitelisted) {
|
||||
event.setCancelled(true);
|
||||
player.sendRichMessage(Messages.GENERIC.COMMAND_BLOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,10 @@ public class GameStageHandler {
|
|||
broadcast(message);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(String message) {
|
||||
broadcast(message);
|
||||
}
|
||||
|
||||
public static void handleCountdownEnd() {
|
||||
broadcast(Messages.GAME.STARTED);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,9 +42,14 @@ public class BossBarService implements RoundListener {
|
|||
public void updateCountdown(Duration timeLeft, Duration totalTime, ROUND_STATE state) {
|
||||
String message = switch (state) {
|
||||
case COUNTDOWN -> Messages.GAME.BOSSBAR_COUNTDOWN;
|
||||
case SAFE_PHASE -> Messages.GAME.BOSSBAR_SAFE_PHASE;
|
||||
case KILL_PHASE -> Messages.GAME.BOSSBAR_KILL_PHASE;
|
||||
default -> throw new IllegalArgumentException("Invalid round state: " + state);
|
||||
case SAFE_PHASE -> Messages.GAME.BOSSBAR_PVP_COUNTDOWN;
|
||||
case KILL_PHASE -> Messages.GAME.BOSSBAR_SAFE_PHASE;
|
||||
default -> {
|
||||
if (state.ordinal() > ROUND_STATE.KILL_PHASE.ordinal()) {
|
||||
yield Messages.GAME.BOSSBAR_KILL_PHASE;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid round state: " + state);
|
||||
}
|
||||
};
|
||||
|
||||
if (message.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.alttd.hunger_games.services;
|
||||
|
||||
import com.alttd.hunger_games.config.Config;
|
||||
import com.alttd.hunger_games.config.Messages;
|
||||
import com.alttd.hunger_games.data_objects.GameStage;
|
||||
import com.alttd.hunger_games.data_objects.PLAYER_STATE;
|
||||
import com.alttd.hunger_games.data_objects.ROUND_STATE;
|
||||
import com.alttd.hunger_games.game.GameStageHandler;
|
||||
import lombok.Setter;
|
||||
|
|
@ -87,9 +87,13 @@ public class Round {
|
|||
|
||||
startCountdown(warmupDuration, () -> {
|
||||
GameStageHandler.handleCountdownEnd();
|
||||
nextStage();
|
||||
nextStage(); // COUNTDOWN -> SAFE_PHASE
|
||||
startCountdown(Config.ROUND.SAFE_PHASE, () -> {
|
||||
nextStage(); // SAFE_PHASE -> KILL_PHASE
|
||||
GameStageHandler.broadcastMessage(Messages.GAME.NEXT_STATE.replace("<round>", roundState.getHumanReadableName()));
|
||||
scheduleNextStage(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void startCountdown(Duration duration, Runnable onEnd) {
|
||||
|
|
@ -120,13 +124,11 @@ public class Round {
|
|||
private void scheduleNextStage(int index) {
|
||||
List<GameStage> gameStageList = Config.ROUND.STAGES;
|
||||
if (gameStageList.isEmpty()) {
|
||||
nextStage(); // Transition to SAFE_PHASE
|
||||
nextStage(); // Transition to KILL_PHASE
|
||||
return;
|
||||
}
|
||||
|
||||
if (gameStageList.size() <= index) {
|
||||
nextStage();
|
||||
nextStage(); // Transition to FINALE
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -134,17 +136,8 @@ public class Round {
|
|||
Duration duration = gameStage.getDuration();
|
||||
|
||||
startCountdown(duration, () -> {
|
||||
if (gameStageList.size() <= index + 1) {
|
||||
nextStage();
|
||||
GameStageHandler.handleStageChange(gameStage.getWorldBorderSize());
|
||||
startCountdown(Duration.ofMinutes(5), this::nextStage);
|
||||
} else {
|
||||
if (index == 0 && roundState.equals(ROUND_STATE.SAFE_PHASE)) {
|
||||
nextStage();
|
||||
}
|
||||
GameStageHandler.handleStageChange(gameStage.getWorldBorderSize());
|
||||
scheduleNextStage(index + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -153,16 +146,7 @@ public class Round {
|
|||
return;
|
||||
}
|
||||
countdownFuture.cancel(true);
|
||||
if (roundState.equals(ROUND_STATE.KILL_PHASE)) {
|
||||
onEnd.run();
|
||||
} else {
|
||||
nextStage();
|
||||
if (roundState.equals(ROUND_STATE.SAFE_PHASE)) {
|
||||
scheduleNextStage(0);
|
||||
} else if (roundState.equals(ROUND_STATE.KILL_PHASE)) {
|
||||
scheduleNextStage(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ public class RoundService implements RoundListener {
|
|||
.forEach(player -> {
|
||||
player.setHealth(20);
|
||||
player.setFoodLevel(20);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
player.setGameMode(GameMode.ADVENTURE);
|
||||
player.getInventory().clear();
|
||||
player.setTotalExperience(0);
|
||||
player.setExp(0.0f);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user