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
58 changes: 31 additions & 27 deletions src/main/java/com/shanebeestudios/hg/api/data/ItemData.java
Original file line number Diff line number Diff line change
@@ -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<ChestType, List<ItemStack>> items = new HashMap<>();
private final Map<ChestType, Integer> count = new HashMap<>();
private final Map<ChestType, WeightedList<ItemStack>> 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<ItemStack> items) {
this.items.put(type, items);
}

public List<ItemStack> 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<ItemStack> weightedItems) {
this.weightedItems.put(type, weightedItems);
}

public WeightedList<ItemStack> 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<ItemStack> value : this.weightedItems.values()) {
count += value.size();
}
return count;
}

/**
* Represents the type of chests in game
* Represents the type of chests in a game.
* <p>Used for logging and refilling</p>
*/
public enum ChestType {
Expand Down Expand Up @@ -97,4 +100,5 @@ public String getName() {
return this.name;
}
}

}
40 changes: 17 additions & 23 deletions src/main/java/com/shanebeestudios/hg/api/data/MobData.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -12,8 +12,8 @@
public class MobData {

private final Random random = new Random();
private final List<MobEntry> dayMobs = new ArrayList<>();
private final List<MobEntry> nightMobs = new ArrayList<>();
private final WeightedList<MobEntry> dayMobs = new WeightedList<>();
private final WeightedList<MobEntry> nightMobs = new WeightedList<>();
private int mobCount;

/**
Expand All @@ -22,7 +22,7 @@ public class MobData {
* @return List of MobEntries
*/
public List<MobEntry> getDayMobs() {
return ImmutableList.copyOf(this.dayMobs);
return ImmutableList.copyOf(this.dayMobs.getEntries());
}

/**
Expand All @@ -32,16 +32,17 @@ public List<MobEntry> 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);
}

/**
Expand All @@ -50,7 +51,7 @@ public void addDayMob(MobEntry mobEntry) {
* @return List of MobEntries
*/
public List<MobEntry> getNightMobs() {
return ImmutableList.copyOf(this.nightMobs);
return ImmutableList.copyOf(this.nightMobs.getEntries());
}

/**
Expand All @@ -60,24 +61,17 @@ public List<MobEntry> 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);
}

/**
Expand All @@ -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<MobEntry> getAllMobs() {
List<MobEntry> mobs = new ArrayList<>();
mobs.addAll(this.dayMobs);
mobs.addAll(this.nightMobs);
mobs.addAll(this.dayMobs.getEntries());
mobs.addAll(this.nightMobs.getEntries());
return mobs;
}

Expand Down
73 changes: 73 additions & 0 deletions src/main/java/com/shanebeestudios/hg/api/util/WeightedList.java
Original file line number Diff line number Diff line change
@@ -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 <T> The type of elements in the list.
*/
public class WeightedList<T> {

private final TreeMap<Double, T> 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<T> 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();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -234,12 +233,7 @@ public void fillChests(Game game, Block block, ChestType chestType) {
* @return Random ItemStack
*/
public ItemStack randomItem(Game game, ChestType chestType) {
List<ItemStack> 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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ItemStack> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 <white>'<aqua>%s<white>'", mobEntryKey);
}
}
}
mobData.setMobCount(count);
return mobData;
}

Expand Down
Loading