diff --git a/build.gradle.kts b/build.gradle.kts index 426de471..0f9494bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -98,12 +98,16 @@ tasks { options.compilerArgs.add("-Xlint:deprecation") } javadoc { + val options = options as StandardJavadocDocletOptions + options.docTitle = "HungerGames API - $projectVersion" + options.overview = "src/main/javadoc/overview.html" options.encoding = Charsets.UTF_8.name() + exclude("com/shanebeestudios/hg/plugin/commands") exclude("com/shanebeestudios/hg/plugin/listeners") - (options as StandardJavadocDocletOptions).links( - "https://jd.papermc.io/paper/1.21.5/", - "https://jd.advntr.dev/api/4.17.0/", + options.links( + "https://jd.papermc.io/paper/26.1.2/", + "https://jd.advntr.dev/api/4.25.0/", "https://tr7zw.github.io/Item-NBT-API/v2-api/" ) diff --git a/src/main/java/com/shanebeestudios/hg/api/data/ItemData.java b/src/main/java/com/shanebeestudios/hg/api/data/ItemData.java index 3adaa363..d2bd8e17 100644 --- a/src/main/java/com/shanebeestudios/hg/api/data/ItemData.java +++ b/src/main/java/com/shanebeestudios/hg/api/data/ItemData.java @@ -1,66 +1,69 @@ package com.shanebeestudios.hg.api.data; +import com.shanebeestudios.hg.api.game.Game; +import com.shanebeestudios.hg.api.util.WeightedList; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; +/** + * Holder of {@link ItemStack Items} for a {@link Game} + */ public class ItemData { - private final Map> items = new HashMap<>(); - private final Map count = new HashMap<>(); + private final Map> weightedItems = new HashMap<>(); public ItemData() { for (ChestType chestType : ChestType.values()) { - this.items.put(chestType, new ArrayList<>()); + this.weightedItems.put(chestType, new WeightedList<>()); } } - public void setItems(ChestType type, List items) { - this.items.put(type, items); - } - - public List getItems(ChestType type) { - return this.items.get(type); - } - /** - * Set item count + * Add a weighted item to the item data. * - * @param chestType ChestType to count - * @param itemCount Amount of items + * @param type Chest type + * @param item Item to add + * @param weight Weight of item */ - public void setItemCount(ChestType chestType, int itemCount) { - this.count.put(chestType, itemCount); + public void addEntry(ChestType type, ItemStack item, int weight) { + this.weightedItems.get(type).add(item, weight); } /** - * Get item count by ChestType + * Get a random item. * - * @param chestType ChestType to get count from - * @return AMount of items by ChestType + * @param type Type of chest + * @return Random item */ - public int getItemCount(ChestType chestType) { - return this.count.get(chestType); + public ItemStack getRandomItem(ChestType type) { + return this.weightedItems.get(type).nextEntry(); + } + + public void setWeightedItems(ChestType type, WeightedList weightedItems) { + this.weightedItems.put(type, weightedItems); + } + + public WeightedList getWeightedItems(ChestType type) { + return this.weightedItems.get(type); } /** - * Get total item count for all chest types + * Get the total item count for all chest types. * * @return Total item count */ public int getTotalItemCount() { int count = 0; - for (int value : this.count.values()) { - count += value; + for (WeightedList value : this.weightedItems.values()) { + count += value.size(); } return count; } /** - * Represents the type of chests in game + * Represents the type of chests in a game. *

Used for logging and refilling

*/ public enum ChestType { @@ -97,4 +100,5 @@ public String getName() { return this.name; } } + } diff --git a/src/main/java/com/shanebeestudios/hg/api/data/MobData.java b/src/main/java/com/shanebeestudios/hg/api/data/MobData.java index e4eaa1c2..0dde449a 100644 --- a/src/main/java/com/shanebeestudios/hg/api/data/MobData.java +++ b/src/main/java/com/shanebeestudios/hg/api/data/MobData.java @@ -1,7 +1,7 @@ package com.shanebeestudios.hg.api.data; import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.ApiStatus; +import com.shanebeestudios.hg.api.util.WeightedList; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -12,8 +12,8 @@ public class MobData { private final Random random = new Random(); - private final List dayMobs = new ArrayList<>(); - private final List nightMobs = new ArrayList<>(); + private final WeightedList dayMobs = new WeightedList<>(); + private final WeightedList nightMobs = new WeightedList<>(); private int mobCount; /** @@ -22,7 +22,7 @@ public class MobData { * @return List of MobEntries */ public List getDayMobs() { - return ImmutableList.copyOf(this.dayMobs); + return ImmutableList.copyOf(this.dayMobs.getEntries()); } /** @@ -32,16 +32,17 @@ public List getDayMobs() { */ public @Nullable MobEntry getRandomDayMob() { if (this.dayMobs.isEmpty()) return null; - return this.dayMobs.get(this.random.nextInt(this.dayMobs.size())); + return this.dayMobs.nextEntry(); } /** * Add a new mob entry to the day mobs * * @param mobEntry Mob entry to add + * @param weight Weight of mob entry */ - public void addDayMob(MobEntry mobEntry) { - this.dayMobs.add(mobEntry); + public void addDayMob(MobEntry mobEntry, int weight) { + this.dayMobs.add(mobEntry, weight); } /** @@ -50,7 +51,7 @@ public void addDayMob(MobEntry mobEntry) { * @return List of MobEntries */ public List getNightMobs() { - return ImmutableList.copyOf(this.nightMobs); + return ImmutableList.copyOf(this.nightMobs.getEntries()); } /** @@ -60,24 +61,17 @@ public List getNightMobs() { */ public @Nullable MobEntry getRandomNightMob() { if (this.nightMobs.isEmpty()) return null; - return this.nightMobs.get(this.random.nextInt(this.nightMobs.size())); + return this.nightMobs.nextEntry(); } /** * Add a new mob entry to the night mobs * * @param mobEntry Mob entry to add + * @param weight Weight of mob entry */ - public void addNightMob(MobEntry mobEntry) { - this.nightMobs.add(mobEntry); - } - - /** - * @hidden - */ - @ApiStatus.Internal - public void setMobCount(int mobCount) { - this.mobCount = mobCount; + public void addNightMob(MobEntry mobEntry, int weight) { + this.nightMobs.add(mobEntry, weight); } /** @@ -86,18 +80,18 @@ public void setMobCount(int mobCount) { * @return Count of all mobs */ public int getMobCount() { - return this.mobCount; + return this.dayMobs.size() + this.nightMobs.size(); } /** - * Get list of all MobEntries + * Get a list of all MobEntries * * @return List of MobEntries */ public List getAllMobs() { List mobs = new ArrayList<>(); - mobs.addAll(this.dayMobs); - mobs.addAll(this.nightMobs); + mobs.addAll(this.dayMobs.getEntries()); + mobs.addAll(this.nightMobs.getEntries()); return mobs; } diff --git a/src/main/java/com/shanebeestudios/hg/api/game/Game.java b/src/main/java/com/shanebeestudios/hg/api/game/Game.java index 55e531c5..7d67ded4 100755 --- a/src/main/java/com/shanebeestudios/hg/api/game/Game.java +++ b/src/main/java/com/shanebeestudios/hg/api/game/Game.java @@ -407,7 +407,7 @@ public void stop() { */ public void stop(boolean death) { if (Config.WORLD_BORDER_ENABLED) { - this.gameBorderData.resetBorder(); + this.gameBorderData.resetBorder(false); } this.gameEntityData.removeEntities(); this.gameScoreboard.resetSidebars(); diff --git a/src/main/java/com/shanebeestudios/hg/api/game/GameBorderData.java b/src/main/java/com/shanebeestudios/hg/api/game/GameBorderData.java index 428d1875..e7f9f3b8 100644 --- a/src/main/java/com/shanebeestudios/hg/api/game/GameBorderData.java +++ b/src/main/java/com/shanebeestudios/hg/api/game/GameBorderData.java @@ -1,13 +1,15 @@ package com.shanebeestudios.hg.api.game; +import com.shanebeestudios.hg.api.util.Util; import com.shanebeestudios.hg.plugin.configs.Config; import com.shanebeestudios.hg.plugin.tasks.WorldBorderTask; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.WorldBorder; import org.bukkit.util.BoundingBox; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -18,7 +20,7 @@ public class GameBorderData extends Data { private final Random random = new Random(); private boolean isDefault; - private Location centerLocation; + private final List centerLocations = new ArrayList<>(); private int finalBorderSize; private int borderCountdownStart; private int borderCountdownEnd; @@ -32,11 +34,11 @@ public class GameBorderData extends Data { this.isDefault = true; } - GameBorderData(Game game, Location centerLocation, int finalSize, int start, int end) { + GameBorderData(Game game, Location centerLocations, int finalSize, int start, int end) { super(game); this.gamePlayerData = game.getGamePlayerData(); this.worldBorder = Bukkit.createWorldBorder(); - this.centerLocation = centerLocation; + this.centerLocations.add(centerLocations); this.finalBorderSize = finalSize; this.borderCountdownStart = start; this.borderCountdownEnd = end; @@ -56,26 +58,34 @@ public WorldBorder getWorldBorder() { * Initialize the {@link WorldBorder} of this game */ public void initialize() { - resetBorder(); + resetBorder(true); this.gamePlayerData.getPlayers().forEach(player -> player.setWorldBorder(this.worldBorder)); this.worldBorderTask = new WorldBorderTask(this.game); } /** * Reset the {@link WorldBorder} of this game + * + * @param start Whether this is a game start or end reset */ - public void resetBorder() { + public void resetBorder(boolean start) { Location center; GameArenaData gameArenaData = this.game.getGameArenaData(); List spawns = gameArenaData.getSpawns(); - if (this.centerLocation != null) { - center = this.centerLocation; - } else { + if (this.centerLocations.isEmpty()) { switch (Config.WORLD_BORDER_CENTER) { // 'first-spawn', 'random-spawn' and 'arena-center' case "first-spawn" -> center = spawns.getFirst(); case "random-spawn" -> center = spawns.get(this.random.nextInt(spawns.size())); default -> center = gameArenaData.getGameRegion().getCenter(); } + } else { + if (start) { + // If starting a new game, pick a random center location + center = this.centerLocations.get(this.random.nextInt(this.centerLocations.size())); + } else { + // If game is ending, reset to arena center + center = gameArenaData.getGameRegion().getCenter(); + } } this.worldBorder.setCenter(center); @@ -103,22 +113,40 @@ public void startShrinking(int closingIn) { } /** - * Set the center of the border of this game + * Add a center location to the border of this game * * @param centerLocation Location of the center */ - public void setCenterLocation(Location centerLocation) { - this.centerLocation = centerLocation; + public void addCenterLocation(Location centerLocation) { + this.centerLocations.add(centerLocation); + } + + /** + * Clear all center locations from the border of this game + */ + public void clearCenterLocations() { + this.centerLocations.clear(); + } + + /** + * Set the center of the border of this game + * + * @param centerLocations Location of the center + */ + public void setCenterLocations(List centerLocations) { + Util.log("Setting center locations for game border"); + this.centerLocations.clear(); + this.centerLocations.addAll(centerLocations); this.isDefault = false; } /** - * Get the center location of the border + * Get a list of center locations of the border * - * @return Center location + * @return Center locations */ - public @Nullable Location getCenterLocation() { - return this.centerLocation; + public @NotNull List getCenterLocations() { + return this.centerLocations; } /** diff --git a/src/main/java/com/shanebeestudios/hg/api/util/WeightedList.java b/src/main/java/com/shanebeestudios/hg/api/util/WeightedList.java new file mode 100644 index 00000000..0dbed94f --- /dev/null +++ b/src/main/java/com/shanebeestudios/hg/api/util/WeightedList.java @@ -0,0 +1,73 @@ +package com.shanebeestudios.hg.api.util; + +import java.util.List; +import java.util.Random; +import java.util.TreeMap; + +/** + * A weighted list that allows for random selection based on entry weights. + * + * @param The type of elements in the list. + */ +public class WeightedList { + + private final TreeMap weightMap = new TreeMap<>(); + private final Random random = new Random(); + private double total = 0; + + /** + * Add an entry to the weighted list with a specified weight. + * + * @param entry The entry to add. + * @param weight The weight of the entry. + * @throws IllegalArgumentException if weight is not positive. + */ + public void add(T entry, int weight) { + if (weight <= 0) { + throw new IllegalArgumentException("Weight must be positive"); + } + this.total += weight; + this.weightMap.put(this.total, entry); + } + + /** + * Get the next entry from the weighted list based on weights. + * + * @return The next entry or null if the list is empty. + */ + public T nextEntry() { + if (this.total == 0) { + return null; + } + double randomValue = this.random.nextDouble() * this.total; + return this.weightMap.higherEntry(randomValue).getValue(); + } + + /** + * Get all entries in the weighted list. + * + * @return An unmodifiable list of entries. + */ + public List getEntries() { + return List.copyOf(this.weightMap.values()); + } + + /** + * Check if the weighted list is empty. + * + * @return True if the list is empty, false otherwise. + */ + public boolean isEmpty() { + return this.total == 0; + } + + /** + * Get the number of entries in the weighted list. + * + * @return The number of entries. + */ + public int size() { + return this.weightMap.size(); + } + +} diff --git a/src/main/java/com/shanebeestudios/hg/plugin/commands/DeleteArenaCommand.java b/src/main/java/com/shanebeestudios/hg/plugin/commands/DeleteArenaCommand.java index 0d40760d..c6239920 100644 --- a/src/main/java/com/shanebeestudios/hg/plugin/commands/DeleteArenaCommand.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/commands/DeleteArenaCommand.java @@ -23,44 +23,59 @@ protected Argument register() { return LiteralArgument.literal("delete-arena") .withPermission(Permissions.COMMAND_DELETE.permission()) .then(CustomArg.GAME.get("game") - .executes(info -> { - CommandSender sender = info.sender(); - Game game = info.args().getByClass("game", Game.class); - assert game != null; - GamePlayerData gamePlayerData = game.getGamePlayerData(); - GameArenaData gameArenaData = game.getGameArenaData(); - String name = gameArenaData.getName(); + .then(LiteralArgument.literal("confirm") + .executes(info -> { + CommandSender sender = info.sender(); + Game game = info.args().getByClass("game", Game.class); + assert game != null; + GamePlayerData gamePlayerData = game.getGamePlayerData(); + GameArenaData gameArenaData = game.getGameArenaData(); + String name = gameArenaData.getName(); - try { - Util.sendPrefixedMessage(sender, this.lang.command_delete_attempt.replace("", name)); + try { + Util.sendPrefixedMessage(sender, this.lang.command_delete_attempt.replace("", name)); - switch (gameArenaData.getStatus()) { - case WAITING, COUNTDOWN, FREE_ROAM, RUNNING -> { - Util.sendMessage(sender, this.lang.command_delete_stopping); - game.getGameBlockData().forceRollback(); - game.stop(false); - } - case ROLLBACK -> { - Util.sendMessage(sender, this.lang.command_delete_rollback); - return; + switch (gameArenaData.getStatus()) { + case WAITING, COUNTDOWN, FREE_ROAM, RUNNING -> { + Util.sendMessage(sender, this.lang.command_delete_stopping); + game.getGameBlockData().forceRollback(); + game.stop(false); + } + case ROLLBACK -> { + Util.sendMessage(sender, this.lang.command_delete_rollback); + return; + } } - } - // This shouldn't happen, why is it here? - if (!gamePlayerData.getPlayers().isEmpty()) { - Util.sendMessage(sender, this.lang.command_delete_kicking); - for (Player player : gamePlayerData.getPlayers()) { - gamePlayerData.leaveGame(player, false); + // This shouldn't happen, why is it here? + if (!gamePlayerData.getPlayers().isEmpty()) { + Util.sendMessage(sender, this.lang.command_delete_kicking); + for (Player player : gamePlayerData.getPlayers()) { + gamePlayerData.leaveGame(player, false); + } } + + this.gameManager.deleteGame(game); + Util.sendMessage(sender, this.lang.command_delete_deleted.replace("", name)); + } catch (Exception e) { + Util.sendMessage(sender, this.lang.command_delete_failed); + Util.sendMessage(sender, "Error Message: " + e.getMessage()); } + })) + .executes(info -> { + CommandSender sender = info.sender(); + Game game = info.args().getByClass("game", Game.class); + assert game != null; - this.gameManager.deleteGame(game); - Util.sendMessage(sender, this.lang.command_delete_deleted.replace("", name)); - } catch (Exception e) { - Util.sendMessage(sender, this.lang.command_delete_failed); - Util.sendMessage(sender, "Error Message: " + e.getMessage()); + String name = game.getGameArenaData().getName(); + if (sender instanceof Player player) { + Util.sendMessage(sender, this.lang.command_delete_confirm.replace("", name), + name); + } else { + Util.sendMessage(sender, this.lang.command_delete_confirm_console.replace("", name)); } - })); + }) + ); } } diff --git a/src/main/java/com/shanebeestudios/hg/plugin/commands/EditCommand.java b/src/main/java/com/shanebeestudios/hg/plugin/commands/EditCommand.java index f3de01f2..6f703d1b 100644 --- a/src/main/java/com/shanebeestudios/hg/plugin/commands/EditCommand.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/commands/EditCommand.java @@ -73,16 +73,23 @@ private Argument border() { saveGame(game); }))) - .then(LiteralArgument.literal("center_location") + .then(LiteralArgument.literal("add_center_location") .then(new Location2DArgument("center_location", LocationType.BLOCK_POSITION) .executes(info -> { Game game = info.args().getByClass("game", Game.class); Location2D centerLocation = info.args().getByClass("center_location", Location2D.class); GameBorderData gameBorderData = game.getGameBorderData(); - gameBorderData.setCenterLocation(convert(centerLocation)); - Util.sendPrefixedMessage(info.sender(), "Border center location set to %s", centerLocation); + gameBorderData.addCenterLocation(convert(centerLocation)); + Util.sendPrefixedMessage(info.sender(), "Border center location added: %s", centerLocation); saveGame(game); - }))); + }))) + .then(LiteralArgument.literal("clear_center_locations") + .executes(info -> { + Game game = info.args().getByClass("game", Game.class); + game.getGameBorderData().clearCenterLocations(); + Util.sendPrefixedMessage(info.sender(), "Border center locations cleared"); + saveGame(game); + })); } @SuppressWarnings("DataFlowIssue") diff --git a/src/main/java/com/shanebeestudios/hg/plugin/configs/ArenaConfig.java b/src/main/java/com/shanebeestudios/hg/plugin/configs/ArenaConfig.java index 609652d0..0db37f11 100755 --- a/src/main/java/com/shanebeestudios/hg/plugin/configs/ArenaConfig.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/configs/ArenaConfig.java @@ -115,6 +115,7 @@ public void loadAllArenas() { @SuppressWarnings("DataFlowIssue") public boolean loadArena(FileConfiguration arenaConfig, String arenaName) { boolean isReady = true; + boolean isDirty = false; List spawns = new ArrayList<>(); Location lobbysign = null; int timer = 0; @@ -192,9 +193,20 @@ public boolean loadArena(FileConfiguration arenaConfig, String arenaName) { if (arenaConfig.isSet("game_border")) { ConfigurationSection borderSection = arenaConfig.getConfigurationSection("game_border"); GameBorderData gameBorderData = game.getGameBorderData(); - if (borderSection.isSet("center_location")) { - Location borderCenter = LocationParser.getBlockLocFromString(borderSection.getString("center_location")); - gameBorderData.setCenterLocation(borderCenter); + + if (borderSection.isSet("center_locations")) { + List centerLocations = borderSection.getStringList("center_locations"); + List centerLocationList = new ArrayList<>(); + for (String locString : centerLocations) { + Location centerLocation = LocationParser.getBlockLocFromString(locString); + centerLocationList.add(centerLocation); + } + gameBorderData.setCenterLocations(centerLocationList); + } else if (borderSection.isSet("center_location")) { // Deprecated (May 5/2026) + String centerLocString = borderSection.getString("center_location"); + Location borderCenter = LocationParser.getBlockLocFromString(centerLocString); + gameBorderData.setCenterLocations(List.of(borderCenter)); + isDirty = true; } if (borderSection.isSet("final_size")) { int borderSize = borderSection.getInt("final_size"); @@ -246,6 +258,9 @@ public boolean loadArena(FileConfiguration arenaConfig, String arenaName) { } else { Util.log("- Loaded arena '%s'", arenaName); } + if (isDirty) { + saveGameToConfig(game); + } return isReady; } @@ -300,11 +315,13 @@ public void saveGameToConfig(Game game) { GameBorderData borderData = game.getGameBorderData(); if (!borderData.isDefault()) { ConfigurationSection borderSection = gameSection.createSection("game_border"); - Location centerLocation = borderData.getCenterLocation(); - if (centerLocation != null) { + List centerLocations = new ArrayList<>(); + for (Location centerLocation : borderData.getCenterLocations()) { String locString = LocationParser.blockLocToString(centerLocation); - borderSection.set("center_location", locString); + centerLocations.add(locString); + } + borderSection.set("center_locations", centerLocations); borderSection.set("final_size", borderData.getFinalBorderSize()); borderSection.set("countdown_start", borderData.getBorderCountdownStart()); borderSection.set("countdown_end", borderData.getBorderCountdownEnd()); diff --git a/src/main/java/com/shanebeestudios/hg/plugin/configs/Language.java b/src/main/java/com/shanebeestudios/hg/plugin/configs/Language.java index 11fd3030..1be05907 100644 --- a/src/main/java/com/shanebeestudios/hg/plugin/configs/Language.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/configs/Language.java @@ -65,6 +65,8 @@ public class Language { public String command_create_session_sign_invalid; // - Delete public String command_delete_attempt; + public String command_delete_confirm; + public String command_delete_confirm_console; public String command_delete_kicking; public String command_delete_stopping; public String command_delete_deleted; @@ -345,6 +347,8 @@ private void loadLang() { this.command_create_session_done = this.lang.getString("command.create.session-done"); // - Delete this.command_delete_attempt = this.lang.getString("command.delete.attempt"); + this.command_delete_confirm = this.lang.getString("command.delete.confirm"); + this.command_delete_confirm_console = this.lang.getString("command.delete.confirm-console"); this.command_delete_kicking = this.lang.getString("command.delete.kicking"); this.command_delete_stopping = this.lang.getString("command.delete.stopping"); this.command_delete_deleted = this.lang.getString("command.delete.deleted"); diff --git a/src/main/java/com/shanebeestudios/hg/plugin/managers/GameManager.java b/src/main/java/com/shanebeestudios/hg/plugin/managers/GameManager.java index 17f673cb..5b34327f 100755 --- a/src/main/java/com/shanebeestudios/hg/plugin/managers/GameManager.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/managers/GameManager.java @@ -13,7 +13,6 @@ import com.shanebeestudios.hg.plugin.configs.Language; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -234,12 +233,7 @@ public void fillChests(Game game, Block block, ChestType chestType) { * @return Random ItemStack */ public ItemStack randomItem(Game game, ChestType chestType) { - List items = game.getGameItemData().getItemData().getItems(chestType); - int r = items.size(); - if (r == 0) return new ItemStack(Material.AIR); - int i = this.random.nextInt(r); - return items.get(i); - + return game.getGameItemData().getItemData().getRandomItem(chestType); } /** diff --git a/src/main/java/com/shanebeestudios/hg/plugin/managers/ItemManager.java b/src/main/java/com/shanebeestudios/hg/plugin/managers/ItemManager.java index bb2efe3b..1b0fc1c5 100644 --- a/src/main/java/com/shanebeestudios/hg/plugin/managers/ItemManager.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/managers/ItemManager.java @@ -66,30 +66,25 @@ private ItemData createItemData(ConfigurationSection itemsSection, @Nullable Gam ItemData itemData = new ItemData(); for (ChestType chestType : ChestType.values()) { - int count = 0; ConfigurationSection chestTypeSection = itemsSection.getConfigurationSection(chestType.getName()); if (chestTypeSection == null) { // If the section does not exist in a game, use defaults if (game != null && this.defaultItemData != null) { - itemData.setItems(chestType, this.defaultItemData.getItems(chestType)); - count += this.defaultItemData.getItemCount(chestType); + itemData.setWeightedItems(chestType, this.defaultItemData.getWeightedItems(chestType)); } } else { - List items = new ArrayList<>(); for (String key : chestTypeSection.getKeys(false)) { ConfigurationSection itemSection = chestTypeSection.getConfigurationSection(key); if (itemSection == null) continue; ItemStack itemStack = ItemParser.parseItem(itemSection); int weight = itemSection.getInt("weight", 1); - for (int i = 0; i < weight; i++) { - items.add(itemStack); + if (weight <= 0) { + continue; } - count++; + itemData.addEntry(chestType, itemStack, weight); } - itemData.setItems(chestType, items); } - itemData.setItemCount(chestType, count); } return itemData; } diff --git a/src/main/java/com/shanebeestudios/hg/plugin/managers/MobManager.java b/src/main/java/com/shanebeestudios/hg/plugin/managers/MobManager.java index 48871c8b..b66dfbff 100644 --- a/src/main/java/com/shanebeestudios/hg/plugin/managers/MobManager.java +++ b/src/main/java/com/shanebeestudios/hg/plugin/managers/MobManager.java @@ -88,7 +88,6 @@ public void loadGameMobs(Game game, ConfigurationSection arenaConfig) { private MobData createMobData(ConfigurationSection mobsSection, @Nullable Game game) { MobData mobData = new MobData(); - int count = 0; String gameName = game != null ? game.getGameArenaData().getName() + ":" : ""; for (String time : Arrays.asList("day", "night")) { if (!mobsSection.contains(time)) continue; @@ -212,20 +211,20 @@ private MobData createMobData(ConfigurationSection mobsSection, @Nullable Game g mobEntry.setDeathMessage(deathMessage); } int weight = mobSection.getInt("weight", 1); - count++; - for (int i = 1; i <= weight; i++) { - if (time.equalsIgnoreCase("day")) { - mobData.addDayMob(mobEntry); - } else { - mobData.addNightMob(mobEntry); - } + if (weight <= 0) { + Util.warning("Invalid weight '%d' for mob entry '%s:%s'", weight, time, sectionKey); + continue; + } + if (time.equalsIgnoreCase("day")) { + mobData.addDayMob(mobEntry, weight); + } else { + mobData.addNightMob(mobEntry, weight); } if (Config.SETTINGS_DEBUG) { Util.log("- Loaded mob entry '%s'", mobEntryKey); } } } - mobData.setMobCount(count); return mobData; } diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html new file mode 100644 index 00000000..600ce23b --- /dev/null +++ b/src/main/javadoc/overview.html @@ -0,0 +1,10 @@ + +

+ HungerGames is a simple yet fun, and very lightweight PvP arena system. +
It provides advanced kits, spawns, and a very simple arena setup. +
If you've never heard of the books/movies HungerGames, it's basically a free for all. +
You must hunt for food and items, and attempt to kill others before they kill you. The last man standing wins! +
Unlike some HungerGames plugins, this one does not require you to setup a whole server for the game. +
You can just easily setup multiple arenas anywhere in the world. +

+ diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index 2bee8c00..7bd59a6b 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -58,6 +58,8 @@ command: session-done: "You're all done, your arena is ready to go!" # Delete delete: + confirm-console: "Please use '/hg delete confirm'" + confirm: 'Are you sure you want to delete the arena ? confirm>Click to confirm' attempt: 'Attempting to delete !' stopping: '- Game running! Stopping..' kicking: '- Players detected! Kicking..' @@ -65,7 +67,6 @@ command: failed: 'Failed to delete arena!' rollback: 'The game is currently rolling back and cannot be deleted right now!' no-exist: "The arena '' does not exist!" - # Edit edit: # ChestRefill