forked from Upstream/mmocore
Fixed fishing drops, new config option to change the chance stat
This commit is contained in:
parent
203728ca50
commit
44a70b5878
@ -7,7 +7,7 @@ import net.Indyuce.mmocore.experience.EXPSource;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.loot.LootBuilder;
|
import net.Indyuce.mmocore.loot.LootBuilder;
|
||||||
import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
|
import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
|
||||||
import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable;
|
import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
package net.Indyuce.mmocore.loot;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used whenever the chance stat appears in MMOCore
|
||||||
|
*
|
||||||
|
* @param <T> Any weighted object, currently either fishing drop
|
||||||
|
* items or loot chest tiers.
|
||||||
|
*/
|
||||||
|
public class RandomWeightedRoll<T extends Weighted> {
|
||||||
|
private final Collection<T> collection;
|
||||||
|
private final T rolled;
|
||||||
|
|
||||||
|
private static final Random RANDOM = new Random();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
for (T item : collection) {
|
||||||
|
partialSum += computeRealWeight(item, chance);
|
||||||
|
if (partialSum > randomCoefficient * sum) {
|
||||||
|
rolled = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("Could not roll item");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The chance stat will make low weight items more
|
||||||
|
* likely to be chosen by the algorithm.
|
||||||
|
*
|
||||||
|
* @return Randomly computed item
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public T rollItem() {
|
||||||
|
return rolled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double weightedSum(double chance) {
|
||||||
|
double sum = 0;
|
||||||
|
for (T item : collection)
|
||||||
|
sum += computeRealWeight(item, chance);
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double CHANCE_COEFFICIENT = 7. / 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* chance = 0 | tier chances are unchanged
|
||||||
|
* chance = +inf | uniform law for any drop item
|
||||||
|
* chance = 100 | all tier chances are taken their square root
|
||||||
|
*
|
||||||
|
* @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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Should this be used
|
||||||
|
private double getTierCoefficient(double initialTierChance, double chance) {
|
||||||
|
/**
|
||||||
|
* - Chance = 0 | tier coefficient is left unchanged.
|
||||||
|
* - Chance -> +oo | all tier coefficients are the same (1)
|
||||||
|
* - Chance = 50 | coefficients become their square roots
|
||||||
|
*
|
||||||
|
return Math.pow(initialTierChance, 1 / Math.pow(1 + CHANCE_COEF * chance, 1 / 3));
|
||||||
|
}*/
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package net.Indyuce.mmocore.loot;
|
||||||
|
|
||||||
|
public interface Weighted {
|
||||||
|
|
||||||
|
public double getWeight();
|
||||||
|
}
|
@ -3,10 +3,11 @@ package net.Indyuce.mmocore.loot.chest;
|
|||||||
import io.lumine.mythic.lib.api.math.ScalingFormula;
|
import io.lumine.mythic.lib.api.math.ScalingFormula;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.loot.Weighted;
|
||||||
import net.Indyuce.mmocore.loot.droptable.DropTable;
|
import net.Indyuce.mmocore.loot.droptable.DropTable;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
public class ChestTier {
|
public class ChestTier implements Weighted {
|
||||||
private final TierEffect effect;
|
private final TierEffect effect;
|
||||||
private final ScalingFormula capacity;
|
private final ScalingFormula capacity;
|
||||||
private final DropTable table;
|
private final DropTable table;
|
||||||
@ -27,6 +28,11 @@ public class ChestTier {
|
|||||||
return chance;
|
return chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getWeight() {
|
||||||
|
return chance;
|
||||||
|
}
|
||||||
|
|
||||||
public DropTable getDropTable() {
|
public DropTable getDropTable() {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import net.Indyuce.mmocore.api.event.LootChestSpawnEvent;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerActivity;
|
import net.Indyuce.mmocore.api.player.PlayerActivity;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.loot.LootBuilder;
|
import net.Indyuce.mmocore.loot.LootBuilder;
|
||||||
|
import net.Indyuce.mmocore.loot.RandomWeightedRoll;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -124,32 +125,7 @@ public class LootChestRegion {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public ChestTier rollTier(PlayerData player) {
|
public ChestTier rollTier(PlayerData player) {
|
||||||
double chance = player.getStats().getStat("CHANCE") * MMOCore.plugin.configManager.lootChestsChanceWeight;
|
return new RandomWeightedRoll<>(player, tiers, MMOCore.plugin.configManager.lootChestsChanceWeight).rollItem();
|
||||||
|
|
||||||
double sum = 0;
|
|
||||||
for (ChestTier tier : tiers)
|
|
||||||
sum += getTierCoefficient(tier.getChance(), chance);
|
|
||||||
Validate.isTrue(sum > 0, "No chest tier was found");
|
|
||||||
|
|
||||||
double cummulated = 0;
|
|
||||||
for (ChestTier tier : tiers) {
|
|
||||||
cummulated += getTierCoefficient(tier.getChance(), chance);
|
|
||||||
if (RANDOM.nextDouble() < cummulated / sum)
|
|
||||||
return tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException("Could not roll chest tier");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final double CHANCE_COEF = 7 / 100;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* - Chance = 0 | tier coefficient is left unchanged.
|
|
||||||
* - Chance -> +oo | all tier coefficients are the same (1)
|
|
||||||
* - Chance = 50 | coefficients become their square roots
|
|
||||||
*/
|
|
||||||
private double getTierCoefficient(double initialTierChance, double chance) {
|
|
||||||
return Math.pow(initialTierChance, 1 / Math.pow(1 + CHANCE_COEF * chance, 1 / 3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getRandomLocation(Location center) {
|
public Location getRandomLocation(Location center) {
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package net.Indyuce.mmocore.loot.droptable.dropitem.fishing;
|
package net.Indyuce.mmocore.loot.fishing;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
||||||
import net.Indyuce.mmocore.loot.LootBuilder;
|
import net.Indyuce.mmocore.loot.LootBuilder;
|
||||||
|
import net.Indyuce.mmocore.loot.Weighted;
|
||||||
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
|
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class FishingDropItem {
|
public class FishingDropItem implements Weighted {
|
||||||
private final RandomAmount experience, tugs;
|
private final RandomAmount experience, tugs;
|
||||||
private final DropItem dropItem;
|
private final DropItem dropItem;
|
||||||
|
|
||||||
@ -23,9 +24,9 @@ public class FishingDropItem {
|
|||||||
Validate.isTrue(dropItem.getWeight() > 0, "A fishing drop table item must have a strictly positive weight");
|
Validate.isTrue(dropItem.getWeight() > 0, "A fishing drop table item must have a strictly positive weight");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Override
|
||||||
public int getWeight() {
|
public double getWeight() {
|
||||||
return (int) Math.floor(getItem().getWeight());
|
return dropItem.getWeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DropItem getItem() {
|
public DropItem getItem() {
|
@ -27,7 +27,7 @@ public class ConfigManager {
|
|||||||
public String partyChatPrefix, noSkillBoundPlaceholder;
|
public String partyChatPrefix, noSkillBoundPlaceholder;
|
||||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||||
public double lootChestsChanceWeight;
|
public double lootChestsChanceWeight, fishingDropsChanceWeight;
|
||||||
public int maxPartyLevelDifference;
|
public int maxPartyLevelDifference;
|
||||||
|
|
||||||
private final FileConfiguration messages;
|
private final FileConfiguration messages;
|
||||||
@ -100,6 +100,7 @@ public class ConfigManager {
|
|||||||
globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50;
|
globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50;
|
||||||
noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message();
|
noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message();
|
||||||
lootChestsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.loot-chests");
|
lootChestsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.loot-chests");
|
||||||
|
fishingDropsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.fishing-drops");
|
||||||
maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
|
maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
|
||||||
|
|
||||||
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
|
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
|
||||||
|
@ -3,9 +3,10 @@ package net.Indyuce.mmocore.manager.profession;
|
|||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.loot.RandomWeightedRoll;
|
||||||
import net.Indyuce.mmocore.loot.chest.condition.Condition;
|
import net.Indyuce.mmocore.loot.chest.condition.Condition;
|
||||||
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
|
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
|
||||||
import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
|
import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -16,8 +17,6 @@ import java.util.logging.Level;
|
|||||||
public class FishingManager extends SpecificProfessionManager {
|
public class FishingManager extends SpecificProfessionManager {
|
||||||
private final Set<FishingDropTable> tables = new LinkedHashSet<>();
|
private final Set<FishingDropTable> tables = new LinkedHashSet<>();
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
|
|
||||||
public FishingManager() {
|
public FishingManager() {
|
||||||
super("on-fish");
|
super("on-fish");
|
||||||
}
|
}
|
||||||
@ -96,25 +95,12 @@ public class FishingManager extends SpecificProfessionManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The chance stat will make low weight items more
|
* The chance stat will make low weight items more
|
||||||
* likely to be chosen by the algorithm
|
* likely to be chosen by the algorithm.
|
||||||
*
|
*
|
||||||
* @return Randomly computed fishing drop item
|
* @return Randomly computed fishing drop item
|
||||||
*/
|
*/
|
||||||
public FishingDropItem getRandomItem(PlayerData player) {
|
public FishingDropItem getRandomItem(PlayerData player) {
|
||||||
double chance = player.getStats().getStat("CHANCE");
|
return new RandomWeightedRoll<>(player, items, MMOCore.plugin.configManager.fishingDropsChanceWeight).rollItem();
|
||||||
|
|
||||||
//chance=0 ->the tier.chance remains the same
|
|
||||||
//chance ->+inf -> the tier.chance becomes the same for everyone, uniform law
|
|
||||||
//chance=8-> tierChance=sqrt(tierChance)
|
|
||||||
double sum = 0;
|
|
||||||
double randomCoefficient=RANDOM.nextDouble();
|
|
||||||
for (FishingDropItem item : items) {
|
|
||||||
sum += Math.pow(item.getItem().getWeight(), 1 / Math.log(1 + chance));
|
|
||||||
if(sum<randomCoefficient)
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NullPointerException("Could not find item in drop table");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ guild-plugin: mmocore
|
|||||||
# all set to 1 by default, this option is really server specific
|
# all set to 1 by default, this option is really server specific
|
||||||
chance-stat-weight:
|
chance-stat-weight:
|
||||||
loot-chests: 1
|
loot-chests: 1
|
||||||
|
fishing-drops: 1
|
||||||
|
|
||||||
# Whether blocks generated with a "cobblegenerator" should
|
# Whether blocks generated with a "cobblegenerator" should
|
||||||
# provide the player with experience points or not
|
# provide the player with experience points or not
|
||||||
|
Loading…
Reference in New Issue
Block a user