mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2025-02-07 12:11:24 +01:00
New capacity
and shuffle
option for block/fishing drop tables
This commit is contained in:
parent
5759f78924
commit
b80cda490c
@ -84,6 +84,7 @@ public class BlockInfo {
|
||||
return table != null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<ItemStack> collectDrops(LootBuilder builder) {
|
||||
return table != null ? table.collect(builder) : new ArrayList<>();
|
||||
}
|
||||
|
@ -1,54 +1,59 @@
|
||||
package net.Indyuce.mmocore.loot;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class LootBuilder {
|
||||
private final PlayerData player;
|
||||
private final List<ItemStack> loot = new ArrayList<>();
|
||||
private final PlayerData player;
|
||||
private final List<ItemStack> loot = new ArrayList<>();
|
||||
|
||||
private double capacity;
|
||||
private double capacity;
|
||||
|
||||
/**
|
||||
* Used to create loot from a drop table
|
||||
*
|
||||
* @param player
|
||||
* Player looting
|
||||
* @param capacity
|
||||
* Capacity is the maximum amount of item weight generated using
|
||||
* this table. If capacity is set to 10, this table cannot drop
|
||||
* an item with 5 weight and another with 6 weight at the saeme
|
||||
* time.
|
||||
*/
|
||||
public LootBuilder(PlayerData player, double capacity) {
|
||||
this.player = player;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
public static double DEFAULT_CAPACITY = 100;
|
||||
|
||||
public PlayerData getEntity() {
|
||||
return player;
|
||||
}
|
||||
public LootBuilder(PlayerData player) {
|
||||
this(player, DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
public List<ItemStack> getLoot() {
|
||||
return loot;
|
||||
}
|
||||
/**
|
||||
* Used to create loot from a drop table
|
||||
*
|
||||
* @param player Player looting
|
||||
* @param capacity Capacity is the maximum amount of item weight generated using
|
||||
* this table. If capacity is set to 10, this table cannot drop
|
||||
* an item with 5 weight and another with 6 weight at the saeme
|
||||
* time.
|
||||
*/
|
||||
public LootBuilder(@NotNull PlayerData player, double capacity) {
|
||||
this.player = player;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public double getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
public PlayerData getEntity() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void addLoot(ItemStack item) {
|
||||
loot.add(item);
|
||||
}
|
||||
public List<ItemStack> getLoot() {
|
||||
return loot;
|
||||
}
|
||||
|
||||
public void addLoot(List<? extends ItemStack> items) {
|
||||
loot.addAll(items);
|
||||
}
|
||||
public double getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public void reduceCapacity(double value) {
|
||||
this.capacity = Math.max(0, capacity - value);
|
||||
}
|
||||
public void addLoot(ItemStack item) {
|
||||
loot.add(item);
|
||||
}
|
||||
|
||||
public void addLoot(List<? extends ItemStack> items) {
|
||||
loot.addAll(items);
|
||||
}
|
||||
|
||||
public void reduceCapacity(double value) {
|
||||
this.capacity = Math.max(0, capacity - value);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmocore.loot;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -17,23 +18,24 @@ public class RandomWeightedRoll<T extends Weighted> {
|
||||
private final T rolled;
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final double CHANCE_COEFFICIENT = 7. / 100;
|
||||
|
||||
public RandomWeightedRoll(PlayerData player, Collection<T> collection, double chanceWeight) {
|
||||
this.collection = collection;
|
||||
|
||||
double partialSum = 0;
|
||||
final double randomCoefficient = RANDOM.nextDouble(), chance = chanceWeight * player.getStats().getStat("CHANCE"), sum = weightedSum(chance);
|
||||
final double randomCoefficient = RANDOM.nextDouble(),
|
||||
effectiveLuck = DropItem.CHANCE_FACTOR * chanceWeight * player.getStats().getStat("CHANCE"),
|
||||
sum = weightedSum(effectiveLuck);
|
||||
|
||||
for (T item : collection) {
|
||||
partialSum += computeRealWeight(item, chance);
|
||||
partialSum += computeRealWeight(item, effectiveLuck);
|
||||
if (partialSum >= randomCoefficient * sum) {
|
||||
rolled = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Could not roll item, the chance is :"+chance);
|
||||
throw new RuntimeException("Could not roll item, effective luck is " + effectiveLuck);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,10 +49,10 @@ public class RandomWeightedRoll<T extends Weighted> {
|
||||
return rolled;
|
||||
}
|
||||
|
||||
private double weightedSum(double chance) {
|
||||
private double weightedSum(double effectiveLuck) {
|
||||
double sum = 0;
|
||||
for (T item : collection)
|
||||
sum += computeRealWeight(item, chance);
|
||||
sum += computeRealWeight(item, effectiveLuck);
|
||||
return sum;
|
||||
}
|
||||
|
||||
@ -62,8 +64,8 @@ public class RandomWeightedRoll<T extends Weighted> {
|
||||
*
|
||||
* @return The real weight of an item considering the player's chance stat.
|
||||
*/
|
||||
private double computeRealWeight(T item, double chance) {
|
||||
return Math.pow(item.getWeight(), 1 / Math.pow(1 + CHANCE_COEFFICIENT * chance, 1. / 3.));
|
||||
private double computeRealWeight(T item, double effectiveLuck) {
|
||||
return Math.pow(item.getWeight(), Math.pow(1 + effectiveLuck, -DropItem.CHANCE_POWER));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,47 +1,55 @@
|
||||
package net.Indyuce.mmocore.loot.chest;
|
||||
|
||||
import io.lumine.mythic.lib.api.math.ScalingFormula;
|
||||
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.loot.Weighted;
|
||||
import net.Indyuce.mmocore.loot.droptable.DropTable;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ChestTier implements Weighted {
|
||||
private final TierEffect effect;
|
||||
private final ScalingFormula capacity;
|
||||
private final DropTable table;
|
||||
private final double chance;
|
||||
private final TierEffect effect;
|
||||
// TODO Capacity should be inherent to drop table
|
||||
// TODO make capacity any numeric formula, parsed with a player
|
||||
@BackwardsCompatibility(version = "1.12.1")
|
||||
@Nullable
|
||||
private final ScalingFormula capacity;
|
||||
private final DropTable table;
|
||||
private final double chance;
|
||||
|
||||
public ChestTier(ConfigurationSection config) {
|
||||
effect = config.isConfigurationSection("effect") ? new TierEffect(config.getConfigurationSection("effect")) : null;
|
||||
capacity = new ScalingFormula(config.get("capacity"));
|
||||
chance = config.getDouble("chance");
|
||||
table = MMOCore.plugin.dropTableManager.loadDropTable(config.get("drops"));
|
||||
}
|
||||
public ChestTier(ConfigurationSection config) {
|
||||
effect = config.isConfigurationSection("effect") ? new TierEffect(config.getConfigurationSection("effect")) : null;
|
||||
capacity = config.contains("capacity") ? new ScalingFormula(config.get("capacity")) : null;
|
||||
chance = config.getDouble("chance");
|
||||
table = MMOCore.plugin.dropTableManager.loadDropTable(config.get("drops"));
|
||||
}
|
||||
|
||||
public double rollCapacity(PlayerData player) {
|
||||
return capacity.calculate(player.getLevel());
|
||||
}
|
||||
public double rollCapacity(@NotNull PlayerData player) {
|
||||
return capacity == null ? table.getCapacity() : capacity.calculate(player.getLevel());
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeight() {
|
||||
return chance;
|
||||
}
|
||||
@Override
|
||||
public double getWeight() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public DropTable getDropTable() {
|
||||
return table;
|
||||
}
|
||||
@NotNull
|
||||
public DropTable getDropTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
public boolean hasEffect() {
|
||||
return effect != null;
|
||||
}
|
||||
public boolean hasEffect() {
|
||||
return effect != null;
|
||||
}
|
||||
|
||||
public TierEffect getEffect() {
|
||||
return effect;
|
||||
}
|
||||
public TierEffect getEffect() {
|
||||
return effect;
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,17 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class DropTable implements PreloadedObject {
|
||||
private final String id;
|
||||
private final Set<DropItem> drops = new LinkedHashSet<>();
|
||||
private final Set<Condition> conditions = new LinkedHashSet<>();
|
||||
private final double capacity;
|
||||
private final boolean shuffle;
|
||||
private final List<DropItem> drops = new ArrayList<>();
|
||||
private final List<Condition> conditions = new ArrayList<>();
|
||||
|
||||
private final PostLoadAction postLoadAction;
|
||||
|
||||
@ -30,11 +32,16 @@ public class DropTable implements PreloadedObject {
|
||||
this.postLoadAction.cacheConfig(config);
|
||||
|
||||
this.id = config.getName();
|
||||
this.shuffle = config.getBoolean("shuffle");
|
||||
this.capacity = config.getDouble("capacity", LootBuilder.DEFAULT_CAPACITY);
|
||||
Validate.isTrue(capacity >= 0, "Capacity must be positive");
|
||||
}
|
||||
|
||||
public DropTable(String id) {
|
||||
this.postLoadAction = generatePostLoadAction();
|
||||
this.id = id;
|
||||
this.capacity = 100;
|
||||
this.shuffle = false;
|
||||
}
|
||||
|
||||
private PostLoadAction generatePostLoadAction() {
|
||||
@ -76,13 +83,27 @@ public class DropTable implements PreloadedObject {
|
||||
drops.add(item);
|
||||
}
|
||||
|
||||
public Set<DropItem> getDrops() {
|
||||
public double getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<DropItem> getDrops() {
|
||||
return drops;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ItemStack> collect(LootBuilder builder) {
|
||||
|
||||
for (DropItem item : drops)
|
||||
// Shuffle items?
|
||||
final List<DropItem> items;
|
||||
if (shuffle) {
|
||||
items = new ArrayList<>(drops);
|
||||
Collections.shuffle(items);
|
||||
} else items = drops;
|
||||
|
||||
// Collect items
|
||||
for (DropItem item : items)
|
||||
if (item.rollChance(builder.getEntity()) && builder.getCapacity() >= item.getWeight()) {
|
||||
item.collect(builder);
|
||||
builder.reduceCapacity(item.getWeight());
|
||||
@ -91,7 +112,8 @@ public class DropTable implements PreloadedObject {
|
||||
return builder.getLoot();
|
||||
}
|
||||
|
||||
public Set<Condition> getConditions() {
|
||||
@NotNull
|
||||
public List<Condition> getConditions() {
|
||||
return conditions;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@ public abstract class DropItem {
|
||||
private final double chance, weight;
|
||||
private final RandomAmount amount;
|
||||
|
||||
private static final double CHANCE_COEFFICIENT = 7. / 100;
|
||||
|
||||
public DropItem(MMOLineConfig config) {
|
||||
chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1;
|
||||
amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1);
|
||||
@ -38,16 +36,14 @@ public abstract class DropItem {
|
||||
return amount.calculateInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* CHANCE stat = 0 | tier chances are unchanged
|
||||
* CHANCE stat = +inf | uniform law for any drop item
|
||||
* CHANCE stat = 100 | all tier chances are taken their square root
|
||||
*
|
||||
* @return The real weight of an item considering the player's CHANCE stat.
|
||||
*/
|
||||
/// TODO make it configurable
|
||||
@Deprecated
|
||||
public static final double CHANCE_FACTOR = 7. / 100, CHANCE_POWER = 0.33333333333;
|
||||
|
||||
public boolean rollChance(PlayerData player) {
|
||||
double value = random.nextDouble();
|
||||
return value < Math.pow(chance, 1 / Math.pow(1 + CHANCE_COEFFICIENT * MMOCore.plugin.configManager.dropItemsChanceWeight* player.getStats().getStat("CHANCE"), 1.0 / 3.0));
|
||||
final double effectiveLuck = CHANCE_FACTOR * MMOCore.plugin.configManager.dropItemsChanceWeight * player.getStats().getStat("CHANCE");
|
||||
final double randomValue = random.nextDouble();
|
||||
return randomValue < Math.pow(chance, Math.pow(1 + effectiveLuck, CHANCE_POWER));
|
||||
}
|
||||
|
||||
public abstract void collect(LootBuilder builder);
|
||||
|
@ -87,7 +87,7 @@ public class BlockListener implements Listener {
|
||||
|
||||
// Find the block drops
|
||||
boolean conditionsMet = !info.hasDropTable() || info.getDropTable().areConditionsMet(new ConditionInstance(player));
|
||||
List<ItemStack> drops = conditionsMet && info.hasDropTable() ? info.getDropTable().collect(new LootBuilder(PlayerData.get(player), 0)) : new ArrayList<>();
|
||||
List<ItemStack> drops = conditionsMet && info.hasDropTable() ? info.getDropTable().collect(new LootBuilder(PlayerData.get(player), info.getDropTable().getCapacity())) : new ArrayList<>();
|
||||
|
||||
/*
|
||||
* Calls the event and listen for cancel & for drops changes... also
|
||||
|
@ -170,7 +170,7 @@ public class FishingListener implements Listener {
|
||||
}
|
||||
|
||||
// Find looted item
|
||||
ItemStack collect = caught.collect(new LootBuilder(playerData, 0));
|
||||
ItemStack collect = caught.collect(new LootBuilder(playerData));
|
||||
if (collect == null) {
|
||||
hook.getWorld().spawnParticle(VParticle.SMOKE.get(), location, 24, 0, 0, 0, .08);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user