forked from Upstream/mmocore
!exp source refactor
This commit is contained in:
parent
a363bc6606
commit
d4071f532e
@ -95,8 +95,11 @@ public class MMOCore extends LuminePlugin {
|
|||||||
|
|
||||||
public boolean shouldDebugSQL = false;
|
public boolean shouldDebugSQL = false;
|
||||||
|
|
||||||
public void load() {
|
public MMOCore() {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* register extra objective, drop items...
|
* register extra objective, drop items...
|
||||||
|
@ -5,8 +5,8 @@ import javax.annotation.Nullable;
|
|||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancellable {
|
public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancellable {
|
||||||
|
@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.event;
|
|||||||
|
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
public class PlayerLevelUpEvent extends PlayerDataEvent {
|
public class PlayerLevelUpEvent extends PlayerDataEvent {
|
||||||
|
@ -1,188 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.potion.PotionType;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
|
||||||
|
|
||||||
public class Profession extends PostLoadObject {
|
|
||||||
private final String id, name;
|
|
||||||
private final ExpCurve expCurve;
|
|
||||||
private final int maxLevel;
|
|
||||||
private final Map<ProfessionOption, Boolean> options = new HashMap<>();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* experience given to the main player level whenever he levels up this
|
|
||||||
* profession
|
|
||||||
*/
|
|
||||||
private final LinearValue experience;
|
|
||||||
|
|
||||||
public Profession(String id, FileConfiguration config) {
|
|
||||||
super(config);
|
|
||||||
|
|
||||||
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");
|
|
||||||
this.name = config.getString("name");
|
|
||||||
Validate.notNull(name, "Could not load name");
|
|
||||||
|
|
||||||
expCurve = config.contains("exp-curve")
|
|
||||||
? MMOCore.plugin.experience.getOrThrow(config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
|
|
||||||
: ExpCurve.DEFAULT;
|
|
||||||
experience = new LinearValue(config.getConfigurationSection("experience"));
|
|
||||||
|
|
||||||
if (config.contains("options"))
|
|
||||||
for (String key : config.getConfigurationSection("options").getKeys(false))
|
|
||||||
try {
|
|
||||||
ProfessionOption option = ProfessionOption.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
options.put(option, config.getBoolean("options." + key));
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING,
|
|
||||||
"Could not load option '" + key + "' from profession '" + id + "': " + exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
maxLevel = config.getInt("max-level");
|
|
||||||
|
|
||||||
if (config.contains("exp-sources"))
|
|
||||||
for (String key : config.getStringList("exp-sources"))
|
|
||||||
try {
|
|
||||||
MMOCore.plugin.professionManager.registerExpSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this));
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING,
|
|
||||||
"Could not register exp source '" + key + "' from profession '" + id + "': " + exception.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* drop tables must be loaded after professions are initialized
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void whenPostLoaded(ConfigurationSection config) {
|
|
||||||
|
|
||||||
if (config.contains("on-fish"))
|
|
||||||
MMOCore.plugin.fishingManager.loadDropTables(config.getConfigurationSection("on-fish"));
|
|
||||||
|
|
||||||
if (config.contains("on-mine"))
|
|
||||||
MMOCore.plugin.mineManager.loadDropTables(config.getConfigurationSection("on-mine"));
|
|
||||||
|
|
||||||
if (config.contains("alchemy-experience")) {
|
|
||||||
|
|
||||||
MMOCore.plugin.alchemyManager.splash = 1 + config.getDouble("alchemy-experience.special.splash") / 100;
|
|
||||||
MMOCore.plugin.alchemyManager.lingering = 1 + config.getDouble("alchemy-experience.special.lingering") / 100;
|
|
||||||
MMOCore.plugin.alchemyManager.extend = 1 + config.getDouble("alchemy-experience.special.extend") / 100;
|
|
||||||
MMOCore.plugin.alchemyManager.upgrade = 1 + config.getDouble("alchemy-experience.special.upgrade") / 100;
|
|
||||||
|
|
||||||
for (String key : config.getConfigurationSection("alchemy-experience.effects").getKeys(false))
|
|
||||||
try {
|
|
||||||
PotionType type = PotionType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
MMOCore.plugin.alchemyManager.registerBaseExperience(type, config.getDouble("alchemy-experience.effects." + key));
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read potion type from " + key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.contains("base-enchant-exp"))
|
|
||||||
for (String key : config.getConfigurationSection("base-enchant-exp").getKeys(false))
|
|
||||||
try {
|
|
||||||
Enchantment enchant = MythicLib.plugin.getVersion().getWrapper().getEnchantmentFromString(key.toLowerCase().replace("-", "_"));
|
|
||||||
MMOCore.plugin.enchantManager.registerBaseExperience(enchant, config.getDouble("base-enchant-exp." + key));
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read enchant from " + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.contains("repair-exp"))
|
|
||||||
for (String key : config.getConfigurationSection("repair-exp").getKeys(false))
|
|
||||||
try {
|
|
||||||
Material material = Material.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
MMOCore.plugin.smithingManager.registerBaseExperience(material, config.getDouble("repair-exp." + key));
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read material from " + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (config.contains("effect-weight"))
|
|
||||||
// for (String key :
|
|
||||||
// config.getConfigurationSection("effect-weight").getKeys(false))
|
|
||||||
// try {
|
|
||||||
// MMOCore.plugin.alchemyManager.registerEffectWeight(PotionEffectType.getByName(key.toUpperCase().replace("-",
|
|
||||||
// "_").replace(" ", "_")), config.getDouble("effect-weight." + key));
|
|
||||||
// } catch (IllegalArgumentException exception) {
|
|
||||||
// MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not
|
|
||||||
// read
|
|
||||||
// potion effect type from " + key);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getOption(ProfessionOption option) {
|
|
||||||
return options.getOrDefault(option, option.getDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExpCurve getExpCurve() {
|
|
||||||
return expCurve;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxLevel() {
|
|
||||||
return maxLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMaxLevel() {
|
|
||||||
return maxLevel > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int calculateExperience(int x) {
|
|
||||||
return (int) experience.calculate(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinearValue getExperience() {
|
|
||||||
return experience;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum ProfessionOption {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When disabled, removes exp holograms when mined
|
|
||||||
*/
|
|
||||||
EXP_HOLOGRAMS(true);
|
|
||||||
|
|
||||||
private final boolean def;
|
|
||||||
|
|
||||||
private ProfessionOption(boolean def) {
|
|
||||||
this.def = def;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getDefault() {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Profession that = (Profession) o;
|
|
||||||
return id.equals(that.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,173 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.inventory.BrewEvent;
|
|
||||||
import org.bukkit.inventory.BrewerInventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.PotionMeta;
|
|
||||||
import org.bukkit.potion.PotionType;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
|
|
||||||
private final List<PotionType> types = new ArrayList<>();
|
|
||||||
|
|
||||||
public BrewPotionExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession);
|
|
||||||
|
|
||||||
if (config.contains("effect"))
|
|
||||||
for (String key : config.getString("effect").split(","))
|
|
||||||
types.add(PotionType.valueOf(key.toUpperCase().replace("-", "_")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, PotionMeta meta) {
|
|
||||||
return hasRightClass(player)
|
|
||||||
&& (types.isEmpty() || new ArrayList<>(types).stream().anyMatch(type -> meta.getBasePotionData().getType() == type));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<BrewPotionExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<BrewPotionExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(BrewEvent event) {
|
|
||||||
Optional<Player> playerOpt = getNearbyPlayer(event.getBlock().getLocation());
|
|
||||||
if (!playerOpt.isPresent())
|
|
||||||
return;
|
|
||||||
|
|
||||||
final ItemStack found = findPotion(event.getContents());
|
|
||||||
if (found != null)
|
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
|
||||||
ItemStack brewn = findPotion(event.getContents());
|
|
||||||
if (brewn == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerData data = PlayerData.get(playerOpt.get());
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
for (BrewPotionExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, (PotionMeta) brewn.getItemMeta()))
|
|
||||||
new PotionUpgrade(found, brewn).process(data.getPlayer());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack findPotion(BrewerInventory inv) {
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
ItemStack item = inv.getItem(j);
|
|
||||||
if (item != null && item.hasItemMeta() && item.getItemMeta() instanceof PotionMeta)
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Player> getNearbyPlayer(Location loc) {
|
|
||||||
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100).findAny();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PotionUpgrade {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if the potion was extended using redstone or upgraded using
|
|
||||||
* glowstone. PREPARE corresponds to when a water bottle is prepared for
|
|
||||||
* later recipes using NETHER STALK
|
|
||||||
*/
|
|
||||||
private double exp;
|
|
||||||
|
|
||||||
// private final PotionMeta old, brewn;
|
|
||||||
|
|
||||||
public PotionUpgrade(ItemStack old, ItemStack brewn) {
|
|
||||||
this(old.getType(), (PotionMeta) old.getItemMeta(), brewn.getType(), (PotionMeta) brewn.getItemMeta());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PotionUpgrade(Material oldPot, PotionMeta old, Material brewnPot, PotionMeta brewn) {
|
|
||||||
|
|
||||||
// this.old = old;
|
|
||||||
// this.brewn = brewn;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* calculate base exp
|
|
||||||
*/
|
|
||||||
|
|
||||||
exp += MMOCore.plugin.alchemyManager.getBaseExperience(brewn.getBasePotionData().getType());
|
|
||||||
|
|
||||||
// !old.getBasePotionData().getType().isUpgradeable() &&
|
|
||||||
// brewn.getBasePotionData().getType().isUpgradeable(),
|
|
||||||
//
|
|
||||||
// !old.getBasePotionData().isExtended() &&
|
|
||||||
// brewn.getBasePotionData().isExtended(),
|
|
||||||
//
|
|
||||||
// !old.getBasePotionData().isUpgraded() &&
|
|
||||||
// brewn.getBasePotionData().isUpgraded());
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EXP modifiers based on brewing conditions
|
|
||||||
*/
|
|
||||||
if (oldPot == Material.POTION && brewnPot == Material.SPLASH_POTION)
|
|
||||||
exp *= MMOCore.plugin.alchemyManager.splash;
|
|
||||||
if (oldPot == Material.POTION && brewnPot == Material.LINGERING_POTION)
|
|
||||||
exp *= MMOCore.plugin.alchemyManager.lingering;
|
|
||||||
if (!old.getBasePotionData().isExtended() && brewn.getBasePotionData().isExtended())
|
|
||||||
exp *= MMOCore.plugin.alchemyManager.extend;
|
|
||||||
if (!old.getBasePotionData().isUpgraded() && brewn.getBasePotionData().isUpgraded())
|
|
||||||
exp *= MMOCore.plugin.alchemyManager.upgrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private Map<PotionEffectType, Double> mapEffectDurations() {
|
|
||||||
// Map<PotionEffectType, Double> map = new HashMap<>();
|
|
||||||
//
|
|
||||||
// /*
|
|
||||||
// * potion level, plus the potion gained duration (max 0 so it does
|
|
||||||
// * not give negative EXP), multiplied by the potion effect weight.
|
|
||||||
// */
|
|
||||||
// brewn.getCustomEffects().forEach(effect -> map.put(effect.getType(),
|
|
||||||
//
|
|
||||||
// (effect.getAmplifier() + 1 + (double) Math.max(0,
|
|
||||||
// effect.getDuration() - getPotionEffect(old,
|
|
||||||
// effect.getType()).orElseGet(() -> new
|
|
||||||
// PotionEffect(PotionEffectType.SPEED, 0, 0)).getDuration()) / 60.)
|
|
||||||
//
|
|
||||||
// * MMOCore.plugin.alchemyManager.getWeight(effect.getType())));
|
|
||||||
//
|
|
||||||
// return map;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private int getTotal(Map<?, Double> map) {
|
|
||||||
// double t = 0;
|
|
||||||
// for (double d : map.values())
|
|
||||||
// t += d;
|
|
||||||
// return (int) t;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private Optional<PotionEffect> getPotionEffect(PotionMeta meta,
|
|
||||||
// PotionEffectType type) {
|
|
||||||
// return meta.getCustomEffects().stream().filter(effect ->
|
|
||||||
// effect.getType() == type).findFirst();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void process(Player player) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* calculate extra exp due to extra effects
|
|
||||||
*/
|
|
||||||
// exp += getTotal(mapEffectDurations());
|
|
||||||
|
|
||||||
giveExperience(PlayerData.get(player), (int) exp, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.inventory.CraftItemEvent;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
import org.bukkit.event.inventory.InventoryAction;
|
|
||||||
|
|
||||||
public class CraftItemExperienceSource extends SpecificExperienceSource<Material> {
|
|
||||||
public final Material material;
|
|
||||||
|
|
||||||
public CraftItemExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<CraftItemExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<CraftItemExperienceSource>() {
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void a(CraftItemEvent event) {
|
|
||||||
if(event.getAction() == InventoryAction.NOTHING ||
|
|
||||||
event.getInventory().getResult() == null) return;
|
|
||||||
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
|
||||||
for (CraftItemExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, event.getInventory().getResult().getType()))
|
|
||||||
source.giveExperience(data, event.getInventory().getResult().getAmount(), event.getInventory().getLocation());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, Material obj) {
|
|
||||||
return material == obj && hasRightClass(player);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.enchantment.EnchantItemEvent;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
|
|
||||||
public class EnchantItemExperienceSource extends ExperienceSource<Void> {
|
|
||||||
private final List<Enchantment> enchants = new ArrayList<>();
|
|
||||||
|
|
||||||
public EnchantItemExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession);
|
|
||||||
|
|
||||||
if (config.contains("enchant"))
|
|
||||||
for (String key : config.getString("enchant").split(","))
|
|
||||||
enchants.add(MythicLib.plugin.getVersion().getWrapper().getEnchantmentFromString(key.toLowerCase().replace("-", "_")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, Void v) {
|
|
||||||
return hasRightClass(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<EnchantItemExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<EnchantItemExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(EnchantItemEvent event) {
|
|
||||||
PlayerData player = PlayerData.get(event.getEnchanter());
|
|
||||||
for (EnchantItemExperienceSource source : getSources())
|
|
||||||
if (source.matches(player, null)) {
|
|
||||||
Map<Enchantment, Integer> ench = new HashMap<>(event.getEnchantsToAdd());
|
|
||||||
|
|
||||||
if (!source.enchants.isEmpty())
|
|
||||||
ench.keySet().removeIf(enchantment -> !source.enchants.contains(enchantment));
|
|
||||||
|
|
||||||
if (ench.isEmpty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
double exp = 0;
|
|
||||||
for (Entry<Enchantment, Integer> entry : ench.entrySet())
|
|
||||||
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
|
|
||||||
giveExperience(player, (int) exp, event.getEnchantBlock().getLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Item;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.player.PlayerFishEvent;
|
|
||||||
import org.bukkit.event.player.PlayerFishEvent.State;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class FishItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
|
||||||
private final Material material;
|
|
||||||
|
|
||||||
public FishItemExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<FishItemExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<FishItemExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(PlayerFishEvent event) {
|
|
||||||
if (event.getState() == State.CAUGHT_FISH) {
|
|
||||||
ItemStack caught = ((Item) event.getCaught()).getItemStack();
|
|
||||||
if (caught.hasItemMeta())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerData data = PlayerData.get(event.getPlayer());
|
|
||||||
for (FishItemExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, caught))
|
|
||||||
source.giveExperience(data, caught.getAmount(), event.getHook().getLocation().add(0, 1.0f, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, ItemStack obj) {
|
|
||||||
return hasRightClass(player) && obj.getType() == material;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
import io.lumine.mythic.lib.api.event.EntityKillEntityEvent;
|
|
||||||
|
|
||||||
public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
|
||||||
public final EntityType type;
|
|
||||||
|
|
||||||
public KillMobExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
type = EntityType.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<KillMobExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<KillMobExperienceSource>() {
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void a(EntityKillEntityEvent event) {
|
|
||||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
|
||||||
if (event.getTarget().isDead() && event.getEntity() instanceof Player && !event.getEntity().hasMetadata("NPC")
|
|
||||||
&& !event.getTarget().hasMetadata("spawner_spawned")) {
|
|
||||||
PlayerData data = PlayerData.get((Player) event.getEntity());
|
|
||||||
|
|
||||||
for (KillMobExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, event.getTarget()))
|
|
||||||
source.giveExperience(data, 1, event.getTarget().getLocation());
|
|
||||||
}
|
|
||||||
}, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, Entity obj) {
|
|
||||||
return hasRightClass(player) && obj.getType() == type;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class MineBlockExperienceSource extends SpecificExperienceSource<Material> {
|
|
||||||
public final Material material;
|
|
||||||
private final boolean silkTouch;
|
|
||||||
private final boolean crop;
|
|
||||||
private final boolean playerPlaced;
|
|
||||||
|
|
||||||
public MineBlockExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
silkTouch = config.getBoolean("silk-touch", true);
|
|
||||||
crop = config.getBoolean("crop", false);
|
|
||||||
playerPlaced = config.getBoolean("player-placed", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<MineBlockExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<MineBlockExperienceSource>() {
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(BlockBreakEvent event) {
|
|
||||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerData data = PlayerData.get(event.getPlayer());
|
|
||||||
|
|
||||||
for (MineBlockExperienceSource source : getSources()) {
|
|
||||||
if (source.silkTouch && hasSilkTouch(event.getPlayer().getInventory().getItemInMainHand()))
|
|
||||||
continue;
|
|
||||||
if (source.crop && !MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock()))
|
|
||||||
continue;
|
|
||||||
if ((!source.playerPlaced) && event.getBlock().hasMetadata("player_placed"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (source.matches(data, event.getBlock().getType()))
|
|
||||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasSilkTouch(ItemStack item) {
|
|
||||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, Material obj) {
|
|
||||||
return material == obj && hasRightClass(player);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class PlaceBlockExperienceSource extends SpecificExperienceSource<Material> {
|
|
||||||
public final Material material;
|
|
||||||
|
|
||||||
public PlaceBlockExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<PlaceBlockExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<PlaceBlockExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void a(BlockPlaceEvent event) {
|
|
||||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerData data = PlayerData.get(event.getPlayer());
|
|
||||||
|
|
||||||
for (PlaceBlockExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, event.getBlock().getType()))
|
|
||||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, Material obj) {
|
|
||||||
return material == obj && hasRightClass(player);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
|
||||||
import org.bukkit.inventory.AnvilInventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.Damageable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
|
|
||||||
private final Material material;
|
|
||||||
|
|
||||||
public RepairItemExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if material is null, the player can repair ANY material in order to
|
|
||||||
* get experience.
|
|
||||||
*/
|
|
||||||
material = config.contains("type") ? Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_")) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, ItemStack item) {
|
|
||||||
return (material == null || item.getType() == material) && hasRightClass(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<RepairItemExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<RepairItemExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(InventoryClickEvent event) {
|
|
||||||
if (event.getInventory() != null && event.getInventory().getType() == InventoryType.ANVIL && event.getSlot() == 2) {
|
|
||||||
|
|
||||||
ItemStack item = event.getCurrentItem();
|
|
||||||
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
|
||||||
|
|
||||||
for (RepairItemExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, item)) {
|
|
||||||
|
|
||||||
if (!(event.getInventory() instanceof AnvilInventory))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (((AnvilInventory) event.getInventory()).getRepairCost() > ((Player) event.getWhoClicked()).getLevel())
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* make sure the items can actually be repaired
|
|
||||||
* before getting the amount of durability repaired
|
|
||||||
*/
|
|
||||||
ItemStack old = event.getInventory().getItem(0);
|
|
||||||
if (old == null || old.getType() == Material.AIR)
|
|
||||||
return;
|
|
||||||
if (old.getType().getMaxDurability() < 30 || item.getType().getMaxDurability() < 10)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!MMOCore.plugin.smithingManager.hasExperience(item.getType()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* calculate exp based on amount of durability which
|
|
||||||
* was repaired, substract damage from old item
|
|
||||||
* durability.
|
|
||||||
*/
|
|
||||||
double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType())
|
|
||||||
* Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100;
|
|
||||||
giveExperience(data, (int) exp, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.block.BlockCookEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class SmeltItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
|
||||||
private final Material material;
|
|
||||||
|
|
||||||
public SmeltItemExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession, config);
|
|
||||||
|
|
||||||
config.validate("type");
|
|
||||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExperienceManager<SmeltItemExperienceSource> newManager() {
|
|
||||||
return new ExperienceManager<SmeltItemExperienceSource>() {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(BlockCookEvent event) {
|
|
||||||
Optional<Player> player = getNearestPlayer(event.getBlock().getLocation());
|
|
||||||
if (!player.isPresent())
|
|
||||||
return;
|
|
||||||
|
|
||||||
ItemStack caught = event.getResult();
|
|
||||||
if (caught.hasItemMeta())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerData data = PlayerData.get(player.get());
|
|
||||||
for (SmeltItemExperienceSource source : getSources())
|
|
||||||
if (source.matches(data, caught))
|
|
||||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Player> getNearestPlayer(Location loc) {
|
|
||||||
final Player[] nearby = loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100)
|
|
||||||
.toArray(Player[]::new);
|
|
||||||
Player selected = null;
|
|
||||||
double lastDist = 100;
|
|
||||||
for (Player p : nearby) {
|
|
||||||
double currDist = p.getLocation().distance(loc);
|
|
||||||
if (currDist < lastDist) {
|
|
||||||
lastDist = currDist;
|
|
||||||
selected = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.ofNullable(selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(PlayerData player, ItemStack obj) {
|
|
||||||
return obj.getType() == material && hasRightClass(player);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source.type;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession.ProfessionOption;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Atrocious API that really needs rewriting
|
|
||||||
*
|
|
||||||
* @author cympe
|
|
||||||
*/
|
|
||||||
public abstract class ExperienceSource<T> {
|
|
||||||
private final Profession profession;
|
|
||||||
private PlayerClass profess;
|
|
||||||
|
|
||||||
public ExperienceSource(Profession profession) {
|
|
||||||
this(profession, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExperienceSource(PlayerClass profess) {
|
|
||||||
this(null, profess);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExperienceSource(Profession profession, PlayerClass profess) {
|
|
||||||
this.profession = profession;
|
|
||||||
this.profess = profess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO remove setter
|
|
||||||
public void setClass(PlayerClass profess) {
|
|
||||||
this.profess = profess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasRightClass(PlayerData data) {
|
|
||||||
return profess == null || profess.equals(data.getProfess());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasProfession() {
|
|
||||||
return profession != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasClass() {
|
|
||||||
return profess != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract ExperienceManager<?> newManager();
|
|
||||||
|
|
||||||
public abstract boolean matches(PlayerData player, T obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives experience to the right profession/class
|
|
||||||
*
|
|
||||||
* @param player Player to give exp to
|
|
||||||
* @param amount Amount of experience given
|
|
||||||
* @param hologramLocation If location is null the default location will be
|
|
||||||
* the player's torso
|
|
||||||
*/
|
|
||||||
public void giveExperience(PlayerData player, int amount, @Nullable Location hologramLocation) {
|
|
||||||
if (hasProfession()) {
|
|
||||||
hologramLocation = !profession.getOption(ProfessionOption.EXP_HOLOGRAMS) ? null
|
|
||||||
: hologramLocation == null ? getPlayerLocation(player) : hologramLocation;
|
|
||||||
player.getCollectionSkills().giveExperience(profession, amount, EXPSource.SOURCE, hologramLocation);
|
|
||||||
} else {
|
|
||||||
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
|
|
||||||
: hologramLocation == null ? getPlayerLocation(player) : hologramLocation;
|
|
||||||
player.giveExperience(amount, EXPSource.SOURCE, hologramLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Location getPlayerLocation(PlayerData player) {
|
|
||||||
return player.isOnline() ? player.getPlayer().getLocation() : null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.experience.source.type;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public abstract class SpecificExperienceSource<T> extends ExperienceSource<T> {
|
|
||||||
private final RandomAmount amount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to register experience sources with SPECIFIC experience outputs.
|
|
||||||
* Other experience sources like ENCHANT have their exp output depend on the
|
|
||||||
* enchanted item. ALCHEMY exp outputs depend on the potion crafted
|
|
||||||
*/
|
|
||||||
public SpecificExperienceSource(Profession profession, MMOLineConfig config) {
|
|
||||||
super(profession);
|
|
||||||
|
|
||||||
config.validate("amount");
|
|
||||||
amount = new RandomAmount(config.getString("amount"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public RandomAmount getAmount() {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int rollAmount() {
|
|
||||||
return amount.calculateInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used when a player needs to gain experience after performing the action
|
|
||||||
* corresponding to this exp source
|
|
||||||
*
|
|
||||||
* @param multiplier
|
|
||||||
* Used by the CraftItem experience source, multiplies the exp
|
|
||||||
* earned by a certain factor. When crafting an item, the
|
|
||||||
* multiplier is equal to the amount of items crafted
|
|
||||||
* @param loc
|
|
||||||
* Location used to display the exp hologram
|
|
||||||
*/
|
|
||||||
public void giveExperience(PlayerData player, int multiplier, Location loc) {
|
|
||||||
super.giveExperience(player, rollAmount() * multiplier, loc);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
package net.Indyuce.mmocore.api.load;
|
package net.Indyuce.mmocore.api.load;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.block.BlockType;
|
import net.Indyuce.mmocore.api.block.BlockType;
|
||||||
@ -16,17 +17,16 @@ import net.Indyuce.mmocore.api.droptable.dropitem.GoldDropItem;
|
|||||||
import net.Indyuce.mmocore.api.droptable.dropitem.MMDropTableDropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.MMDropTableDropItem;
|
||||||
import net.Indyuce.mmocore.api.droptable.dropitem.NoteDropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.NoteDropItem;
|
||||||
import net.Indyuce.mmocore.api.droptable.dropitem.VanillaDropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.VanillaDropItem;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.source.BrewPotionExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.BrewPotionExperienceSource;
|
import net.Indyuce.mmocore.experience.source.CraftItemExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.CraftItemExperienceSource;
|
import net.Indyuce.mmocore.experience.source.EnchantItemExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.EnchantItemExperienceSource;
|
import net.Indyuce.mmocore.experience.source.FishItemExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.FishItemExperienceSource;
|
import net.Indyuce.mmocore.experience.source.KillMobExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.KillMobExperienceSource;
|
import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.MineBlockExperienceSource;
|
import net.Indyuce.mmocore.experience.source.PlaceBlockExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.PlaceBlockExperienceSource;
|
import net.Indyuce.mmocore.experience.source.RepairItemExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.RepairItemExperienceSource;
|
import net.Indyuce.mmocore.experience.source.SmeltItemExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.SmeltItemExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.quest.objective.ClickonObjective;
|
import net.Indyuce.mmocore.api.quest.objective.ClickonObjective;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.GoToObjective;
|
import net.Indyuce.mmocore.api.quest.objective.GoToObjective;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.KillMobObjective;
|
import net.Indyuce.mmocore.api.quest.objective.KillMobObjective;
|
||||||
@ -129,33 +129,33 @@ public class DefaultMMOLoader extends MMOLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession) {
|
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||||
if (config.getKey().equals("fishitem"))
|
if (config.getKey().equals("fishitem"))
|
||||||
return new FishItemExperienceSource(profession, config);
|
return new FishItemExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("killmob"))
|
if (config.getKey().equals("killmob"))
|
||||||
return new KillMobExperienceSource(profession, config);
|
return new KillMobExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("mineblock"))
|
if (config.getKey().equals("mineblock"))
|
||||||
return new MineBlockExperienceSource(profession, config);
|
return new MineBlockExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("placeblock"))
|
if (config.getKey().equals("placeblock"))
|
||||||
return new PlaceBlockExperienceSource(profession, config);
|
return new PlaceBlockExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("brewpotion"))
|
if (config.getKey().equals("brewpotion"))
|
||||||
return new BrewPotionExperienceSource(profession, config);
|
return new BrewPotionExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("smeltitem"))
|
if (config.getKey().equals("smeltitem"))
|
||||||
return new SmeltItemExperienceSource(profession, config);
|
return new SmeltItemExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("enchantitem"))
|
if (config.getKey().equals("enchantitem"))
|
||||||
return new EnchantItemExperienceSource(profession, config);
|
return new EnchantItemExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("repairitem"))
|
if (config.getKey().equals("repairitem"))
|
||||||
return new RepairItemExperienceSource(profession, config);
|
return new RepairItemExperienceSource(dispenser, config);
|
||||||
|
|
||||||
if (config.getKey().equals("craftitem"))
|
if (config.getKey().equals("craftitem"))
|
||||||
return new CraftItemExperienceSource(profession, config);
|
return new CraftItemExperienceSource(dispenser, config);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package net.Indyuce.mmocore.api.load;
|
package net.Indyuce.mmocore.api.load;
|
||||||
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.block.BlockType;
|
import net.Indyuce.mmocore.api.block.BlockType;
|
||||||
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
||||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MMOLoader was initially an interface but it is now a
|
||||||
|
* class so devs do not have to add a new method
|
||||||
|
* everytime the class is updated.
|
||||||
|
*/
|
||||||
public class MMOLoader {
|
public class MMOLoader {
|
||||||
|
|
||||||
/*
|
|
||||||
* MMOLoader was initially an interface but it is now a class so devs do not
|
|
||||||
* have to add a new method everytime the class is updated.
|
|
||||||
*/
|
|
||||||
public Condition loadCondition(MMOLineConfig config) {
|
public Condition loadCondition(MMOLineConfig config) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ public class MMOLoader {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession) {
|
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@ import net.Indyuce.mmocore.MMOCore;
|
|||||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||||
import net.Indyuce.mmocore.api.Waypoint;
|
import net.Indyuce.mmocore.api.Waypoint;
|
||||||
import net.Indyuce.mmocore.api.event.*;
|
import net.Indyuce.mmocore.api.event.*;
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
|
||||||
import net.Indyuce.mmocore.api.experience.PlayerProfessions;
|
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
|
||||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||||
@ -21,6 +19,8 @@ import net.Indyuce.mmocore.api.player.stats.StatType;
|
|||||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.listener.SpellCast.SkillCasting;
|
import net.Indyuce.mmocore.listener.SpellCast.SkillCasting;
|
||||||
import net.Indyuce.mmocore.manager.SoundManager;
|
import net.Indyuce.mmocore.manager.SoundManager;
|
||||||
import net.Indyuce.mmocore.skill.CasterMetadata;
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
@ -465,7 +465,7 @@ public class PlayerData extends OfflinePlayerData {
|
|||||||
* @param hologramLocation Location used to display the hologram. If it's null, no
|
* @param hologramLocation Location used to display the hologram. If it's null, no
|
||||||
* hologram will be displayed
|
* hologram will be displayed
|
||||||
*/
|
*/
|
||||||
public void giveExperience(int value, EXPSource source, @Nullable Location hologramLocation) {
|
public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation) {
|
||||||
if (hasReachedMaxLevel()) {
|
if (hasReachedMaxLevel()) {
|
||||||
setExperience(0);
|
setExperience(0);
|
||||||
return;
|
return;
|
||||||
@ -478,7 +478,7 @@ public class PlayerData extends OfflinePlayerData {
|
|||||||
value = MMOCore.plugin.boosterManager.calculateExp(null, value);
|
value = MMOCore.plugin.boosterManager.calculateExp(null, value);
|
||||||
value *= 1 + getStats().getStat(StatType.ADDITIONAL_EXPERIENCE) / 100;
|
value *= 1 + getStats().getStat(StatType.ADDITIONAL_EXPERIENCE) / 100;
|
||||||
|
|
||||||
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source);
|
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, (int) value, source);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
|
@ -7,18 +7,20 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
|
|||||||
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.ExpCurve;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
|
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
|
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.ResourceHandler;
|
import net.Indyuce.mmocore.api.player.profess.resource.ResourceHandler;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
import net.Indyuce.mmocore.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
||||||
|
import net.Indyuce.mmocore.experience.ExpCurve;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -122,17 +124,17 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
"Could not load option '" + key + "' from class '" + key + "': " + exception.getMessage());
|
"Could not load option '" + key + "' from class '" + key + "': " + exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.contains("main-exp-sources"))
|
if (config.contains("main-exp-sources")) {
|
||||||
|
ExperienceDispenser dispenser = new MainExperienceDispenser(this);
|
||||||
for (String key : config.getStringList("main-exp-sources"))
|
for (String key : config.getStringList("main-exp-sources"))
|
||||||
try {
|
try {
|
||||||
ExperienceSource<?> source = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key),
|
ExperienceSource<?> source = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser);
|
||||||
null);
|
|
||||||
source.setClass(this);
|
|
||||||
MMOCore.plugin.professionManager.registerExpSource(source);
|
MMOCore.plugin.professionManager.registerExpSource(source);
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '"
|
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '"
|
||||||
+ id + "': " + exception.getMessage());
|
+ id + "': " + exception.getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config.contains("triggers"))
|
if (config.contains("triggers"))
|
||||||
for (String key : config.getConfigurationSection("triggers").getKeys(false)) {
|
for (String key : config.getConfigurationSection("triggers").getKeys(false)) {
|
||||||
|
@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.player.stats;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
@ -12,7 +12,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
@ -3,9 +3,9 @@ package net.Indyuce.mmocore.api.quest.trigger;
|
|||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.experience.ExperienceInfo;
|
import net.Indyuce.mmocore.experience.ExperienceInfo;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
@ -8,9 +8,9 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||||
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
||||||
|
@ -6,7 +6,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
||||||
|
@ -9,9 +9,9 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
||||||
|
@ -6,7 +6,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
|
||||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||||
|
@ -9,8 +9,8 @@ import org.bukkit.command.CommandSender;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||||
import net.Indyuce.mmocore.api.experience.Booster;
|
import net.Indyuce.mmocore.experience.Booster;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
||||||
|
@ -5,7 +5,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Booster;
|
import net.Indyuce.mmocore.experience.Booster;
|
||||||
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.ChatColor;
|
|||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Booster;
|
import net.Indyuce.mmocore.experience.Booster;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode;
|
||||||
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
import io.lumine.mythic.lib.mmolibcommands.api.Parameter;
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package net.Indyuce.mmocore.comp.mythicmobs;
|
package net.Indyuce.mmocore.comp.mythicmobs;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.load.MMOLoader;
|
import net.Indyuce.mmocore.api.load.MMOLoader;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
||||||
@ -37,12 +38,12 @@ public class MythicMobsMMOLoader extends MMOLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession) {
|
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||||
|
|
||||||
if (config.getKey().equalsIgnoreCase("killmythicmob"))
|
if (config.getKey().equalsIgnoreCase("killmythicmob"))
|
||||||
return new KillMythicMobExperienceSource(profession, config);
|
return new KillMythicMobExperienceSource(dispenser, config);
|
||||||
if (config.getKey().equalsIgnoreCase("killmythicfaction"))
|
if (config.getKey().equalsIgnoreCase("killmythicfaction"))
|
||||||
return new KillMythicFactionExperienceSource(profession, config);
|
return new KillMythicFactionExperienceSource(dispenser, config);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
package net.Indyuce.mmocore.comp.mythicmobs.load;
|
package net.Indyuce.mmocore.comp.mythicmobs.load;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
|
||||||
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class KillMythicFactionExperienceSource extends SpecificExperienceSource<String> {
|
public class KillMythicFactionExperienceSource extends SpecificExperienceSource<String> {
|
||||||
private final String factionName;
|
private final String factionName;
|
||||||
|
|
||||||
public KillMythicFactionExperienceSource(Profession profession, MMOLineConfig config) {
|
public KillMythicFactionExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
super(profession, config);
|
super(dispenser, config);
|
||||||
|
|
||||||
config.validate("name");
|
config.validate("name");
|
||||||
factionName = config.getString("name");
|
factionName = config.getString("name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExperienceManager<KillMythicFactionExperienceSource> newManager() {
|
public ExperienceSourceManager<KillMythicFactionExperienceSource> newManager() {
|
||||||
return new ExperienceManager<KillMythicFactionExperienceSource>() {
|
return new ExperienceSourceManager<KillMythicFactionExperienceSource>() {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void a(MythicMobDeathEvent event) {
|
public void a(MythicMobDeathEvent event) {
|
||||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
||||||
@ -42,7 +41,7 @@ public class KillMythicFactionExperienceSource extends SpecificExperienceSource<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(PlayerData player, String name) {
|
public boolean matchesParameter(PlayerData player, String name) {
|
||||||
return hasRightClass(player) && name.equals(factionName);
|
return name.equals(factionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
package net.Indyuce.mmocore.comp.mythicmobs.load;
|
package net.Indyuce.mmocore.comp.mythicmobs.load;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
|
||||||
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
|
|
||||||
public class KillMythicMobExperienceSource extends SpecificExperienceSource<String> {
|
public class KillMythicMobExperienceSource extends SpecificExperienceSource<String> {
|
||||||
private final String internalName;
|
private final String internalName;
|
||||||
|
|
||||||
public KillMythicMobExperienceSource(Profession profession, MMOLineConfig config) {
|
public KillMythicMobExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
super(profession, config);
|
super(dispenser, config);
|
||||||
|
|
||||||
config.validate("type");
|
config.validate("type");
|
||||||
internalName = config.getString("type");
|
internalName = config.getString("type");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExperienceManager<KillMythicMobExperienceSource> newManager() {
|
public ExperienceSourceManager<KillMythicMobExperienceSource> newManager() {
|
||||||
return new ExperienceManager<KillMythicMobExperienceSource>() {
|
return new ExperienceSourceManager<KillMythicMobExperienceSource>() {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void a(MythicMobDeathEvent event) {
|
public void a(MythicMobDeathEvent event) {
|
||||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
||||||
@ -41,7 +40,7 @@ public class KillMythicMobExperienceSource extends SpecificExperienceSource<Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(PlayerData player, String name) {
|
public boolean matchesParameter(PlayerData player, String name) {
|
||||||
return hasRightClass(player) && name.equals(internalName);
|
return name.equals(internalName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import io.lumine.mythic.lib.MythicLib;
|
|||||||
import io.lumine.mythic.lib.api.util.AltChar;
|
import io.lumine.mythic.lib.api.util.AltChar;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
public enum EXPSource {
|
public enum EXPSource {
|
||||||
SOURCE,
|
SOURCE,
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
public class ExperienceInfo {
|
public class ExperienceInfo {
|
||||||
private final Profession profess;
|
private final Profession profess;
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.experience;
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
@ -128,7 +128,7 @@ public class PlayerProfessions {
|
|||||||
return profession.hasMaxLevel() && getLevel(profession) >= profession.getMaxLevel();
|
return profession.hasMaxLevel() && getLevel(profession) >= profession.getMaxLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void giveExperience(Profession profession, int value, EXPSource source, @Nullable Location hologramLocation) {
|
public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation) {
|
||||||
if (hasReachedMaxLevel(profession)) {
|
if (hasReachedMaxLevel(profession)) {
|
||||||
setExperience(profession, 0);
|
setExperience(profession, 0);
|
||||||
return;
|
return;
|
||||||
@ -140,12 +140,12 @@ public class PlayerProfessions {
|
|||||||
if (hologramLocation != null && playerData.isOnline())
|
if (hologramLocation != null && playerData.isOnline())
|
||||||
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
|
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
|
||||||
|
|
||||||
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, value, source);
|
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exp.put(profession.getId(), exp.containsKey(profession.getId()) ? exp.get(profession.getId()) + value : value);
|
exp.put(profession.getId(), exp.containsKey(profession.getId()) ? exp.get(profession.getId()) + event.getExperience() : event.getExperience());
|
||||||
int needed, exp, level, oldLevel = getLevel(profession);
|
int needed, exp, level, oldLevel = getLevel(profession);
|
||||||
|
|
||||||
/*
|
/*
|
191
src/main/java/net/Indyuce/mmocore/experience/Profession.java
Normal file
191
src/main/java/net/Indyuce/mmocore/experience/Profession.java
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ProfessionExperienceDispenser;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.potion.PotionType;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class Profession extends PostLoadObject {
|
||||||
|
private final String id, name;
|
||||||
|
private final ExpCurve expCurve;
|
||||||
|
private final int maxLevel;
|
||||||
|
private final Map<ProfessionOption, Boolean> options = new HashMap<>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* experience given to the main player level whenever he levels up this
|
||||||
|
* profession
|
||||||
|
*/
|
||||||
|
private final LinearValue experience;
|
||||||
|
|
||||||
|
public Profession(String id, FileConfiguration config) {
|
||||||
|
super(config);
|
||||||
|
|
||||||
|
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||||
|
this.name = config.getString("name");
|
||||||
|
Validate.notNull(name, "Could not load name");
|
||||||
|
|
||||||
|
expCurve = config.contains("exp-curve")
|
||||||
|
? MMOCore.plugin.experience.getOrThrow(config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
|
||||||
|
: ExpCurve.DEFAULT;
|
||||||
|
experience = new LinearValue(config.getConfigurationSection("experience"));
|
||||||
|
|
||||||
|
if (config.contains("options"))
|
||||||
|
for (String key : config.getConfigurationSection("options").getKeys(false))
|
||||||
|
try {
|
||||||
|
ProfessionOption option = ProfessionOption.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
options.put(option, config.getBoolean("options." + key));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
MMOCore.plugin.getLogger().log(Level.WARNING,
|
||||||
|
"Could not load option '" + key + "' from profession '" + id + "': " + exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
maxLevel = config.getInt("max-level");
|
||||||
|
|
||||||
|
if (config.contains("exp-sources")) {
|
||||||
|
ExperienceDispenser dispenser = new ProfessionExperienceDispenser(this);
|
||||||
|
for (String key : config.getStringList("exp-sources"))
|
||||||
|
try {
|
||||||
|
MMOCore.plugin.professionManager.registerExpSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
MMOCore.plugin.getLogger().log(Level.WARNING,
|
||||||
|
"Could not register exp source '" + key + "' from profession '" + id + "': " + exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* drop tables must be loaded after professions are initialized
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void whenPostLoaded(ConfigurationSection config) {
|
||||||
|
|
||||||
|
if (config.contains("on-fish"))
|
||||||
|
MMOCore.plugin.fishingManager.loadDropTables(config.getConfigurationSection("on-fish"));
|
||||||
|
|
||||||
|
if (config.contains("on-mine"))
|
||||||
|
MMOCore.plugin.mineManager.loadDropTables(config.getConfigurationSection("on-mine"));
|
||||||
|
|
||||||
|
if (config.contains("alchemy-experience")) {
|
||||||
|
|
||||||
|
MMOCore.plugin.alchemyManager.splash = 1 + config.getDouble("alchemy-experience.special.splash") / 100;
|
||||||
|
MMOCore.plugin.alchemyManager.lingering = 1 + config.getDouble("alchemy-experience.special.lingering") / 100;
|
||||||
|
MMOCore.plugin.alchemyManager.extend = 1 + config.getDouble("alchemy-experience.special.extend") / 100;
|
||||||
|
MMOCore.plugin.alchemyManager.upgrade = 1 + config.getDouble("alchemy-experience.special.upgrade") / 100;
|
||||||
|
|
||||||
|
for (String key : config.getConfigurationSection("alchemy-experience.effects").getKeys(false))
|
||||||
|
try {
|
||||||
|
PotionType type = PotionType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
MMOCore.plugin.alchemyManager.registerBaseExperience(type, config.getDouble("alchemy-experience.effects." + key));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read potion type from " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.contains("base-enchant-exp"))
|
||||||
|
for (String key : config.getConfigurationSection("base-enchant-exp").getKeys(false))
|
||||||
|
try {
|
||||||
|
Enchantment enchant = MythicLib.plugin.getVersion().getWrapper().getEnchantmentFromString(key.toLowerCase().replace("-", "_"));
|
||||||
|
MMOCore.plugin.enchantManager.registerBaseExperience(enchant, config.getDouble("base-enchant-exp." + key));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read enchant from " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.contains("repair-exp"))
|
||||||
|
for (String key : config.getConfigurationSection("repair-exp").getKeys(false))
|
||||||
|
try {
|
||||||
|
Material material = Material.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
MMOCore.plugin.smithingManager.registerBaseExperience(material, config.getDouble("repair-exp." + key));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not read material from " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (config.contains("effect-weight"))
|
||||||
|
// for (String key :
|
||||||
|
// config.getConfigurationSection("effect-weight").getKeys(false))
|
||||||
|
// try {
|
||||||
|
// MMOCore.plugin.alchemyManager.registerEffectWeight(PotionEffectType.getByName(key.toUpperCase().replace("-",
|
||||||
|
// "_").replace(" ", "_")), config.getDouble("effect-weight." + key));
|
||||||
|
// } catch (IllegalArgumentException exception) {
|
||||||
|
// MMOCore.log(Level.WARNING, "[PlayerProfessions:" + id + "] Could not
|
||||||
|
// read
|
||||||
|
// potion effect type from " + key);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getOption(ProfessionOption option) {
|
||||||
|
return options.getOrDefault(option, option.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExpCurve getExpCurve() {
|
||||||
|
return expCurve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLevel() {
|
||||||
|
return maxLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMaxLevel() {
|
||||||
|
return maxLevel > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int calculateExperience(int x) {
|
||||||
|
return (int) experience.calculate(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinearValue getExperience() {
|
||||||
|
return experience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum ProfessionOption {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When disabled, removes exp holograms when mined
|
||||||
|
*/
|
||||||
|
EXP_HOLOGRAMS(true);
|
||||||
|
|
||||||
|
private final boolean def;
|
||||||
|
|
||||||
|
private ProfessionOption(boolean def) {
|
||||||
|
this.def = def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getDefault() {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Profession that = (Profession) o;
|
||||||
|
return id.equals(that.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.provider;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to differenciate between the main class experience
|
||||||
|
* and experience given in a specific profession
|
||||||
|
*/
|
||||||
|
public interface ExperienceDispenser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when experience is gained in main class/profession
|
||||||
|
*
|
||||||
|
* @param playerData Player gaining the experience
|
||||||
|
* @param experience Experience gained. Note that it is a double
|
||||||
|
* because it gets converted to an integer at
|
||||||
|
* the very last moment in MMOCore
|
||||||
|
* @param hologramLocation Location of displayed hologram, nothing
|
||||||
|
* is displayed if it's null
|
||||||
|
*/
|
||||||
|
void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation);
|
||||||
|
|
||||||
|
boolean matches(PlayerData playerData);
|
||||||
|
|
||||||
|
default Location getPlayerLocation(PlayerData player) {
|
||||||
|
return player.isOnline() ? player.getPlayer().getLocation() : null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.provider;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||||
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class MainExperienceDispenser implements ExperienceDispenser {
|
||||||
|
private final PlayerClass profess;
|
||||||
|
|
||||||
|
public MainExperienceDispenser(PlayerClass profess) {
|
||||||
|
this.profess = profess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation) {
|
||||||
|
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
|
||||||
|
: hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation;
|
||||||
|
playerData.giveExperience(experience, EXPSource.SOURCE, hologramLocation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(PlayerData playerData) {
|
||||||
|
return playerData.getProfess().equals(profess);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.provider;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class ProfessionExperienceDispenser implements ExperienceDispenser {
|
||||||
|
private final Profession profession;
|
||||||
|
|
||||||
|
public ProfessionExperienceDispenser(Profession profession) {
|
||||||
|
this.profession = profession;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation) {
|
||||||
|
hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null
|
||||||
|
: hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation;
|
||||||
|
playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(PlayerData playerData) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.inventory.BrewEvent;
|
||||||
|
import org.bukkit.inventory.BrewerInventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.bukkit.potion.PotionType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
|
||||||
|
private final List<PotionType> types = new ArrayList<>();
|
||||||
|
|
||||||
|
public BrewPotionExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser);
|
||||||
|
|
||||||
|
if (config.contains("effect"))
|
||||||
|
for (String key : config.getString("effect").split(","))
|
||||||
|
types.add(PotionType.valueOf(key.toUpperCase().replace("-", "_")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, PotionMeta meta) {
|
||||||
|
return types.isEmpty() || new ArrayList<>(types).stream().anyMatch(type -> meta.getBasePotionData().getType() == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<BrewPotionExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<BrewPotionExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(BrewEvent event) {
|
||||||
|
Optional<Player> playerOpt = getNearbyPlayer(event.getBlock().getLocation());
|
||||||
|
if (!playerOpt.isPresent())
|
||||||
|
return;
|
||||||
|
|
||||||
|
final ItemStack found = findPotion(event.getContents());
|
||||||
|
if (found != null)
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||||
|
ItemStack brewn = findPotion(event.getContents());
|
||||||
|
if (brewn == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerData data = PlayerData.get(playerOpt.get());
|
||||||
|
for (BrewPotionExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, (PotionMeta) brewn.getItemMeta()))
|
||||||
|
new PotionUpgrade(found, brewn).process(data.getPlayer());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack findPotion(BrewerInventory inv) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
ItemStack item = inv.getItem(j);
|
||||||
|
if (item != null && item.hasItemMeta() && item.getItemMeta() instanceof PotionMeta)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Player> getNearbyPlayer(Location loc) {
|
||||||
|
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100).findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PotionUpgrade {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the potion was extended using redstone or upgraded using
|
||||||
|
* glowstone. PREPARE corresponds to when a water bottle is prepared for
|
||||||
|
* later recipes using NETHER STALK
|
||||||
|
*/
|
||||||
|
private double exp;
|
||||||
|
|
||||||
|
// private final PotionMeta old, brewn;
|
||||||
|
|
||||||
|
public PotionUpgrade(ItemStack old, ItemStack brewn) {
|
||||||
|
this(old.getType(), (PotionMeta) old.getItemMeta(), brewn.getType(), (PotionMeta) brewn.getItemMeta());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PotionUpgrade(Material oldPot, PotionMeta old, Material brewnPot, PotionMeta brewn) {
|
||||||
|
|
||||||
|
// this.old = old;
|
||||||
|
// this.brewn = brewn;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate base exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
exp += MMOCore.plugin.alchemyManager.getBaseExperience(brewn.getBasePotionData().getType());
|
||||||
|
|
||||||
|
// !old.getBasePotionData().getType().isUpgradeable() &&
|
||||||
|
// brewn.getBasePotionData().getType().isUpgradeable(),
|
||||||
|
//
|
||||||
|
// !old.getBasePotionData().isExtended() &&
|
||||||
|
// brewn.getBasePotionData().isExtended(),
|
||||||
|
//
|
||||||
|
// !old.getBasePotionData().isUpgraded() &&
|
||||||
|
// brewn.getBasePotionData().isUpgraded());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXP modifiers based on brewing conditions
|
||||||
|
*/
|
||||||
|
if (oldPot == Material.POTION && brewnPot == Material.SPLASH_POTION)
|
||||||
|
exp *= MMOCore.plugin.alchemyManager.splash;
|
||||||
|
if (oldPot == Material.POTION && brewnPot == Material.LINGERING_POTION)
|
||||||
|
exp *= MMOCore.plugin.alchemyManager.lingering;
|
||||||
|
if (!old.getBasePotionData().isExtended() && brewn.getBasePotionData().isExtended())
|
||||||
|
exp *= MMOCore.plugin.alchemyManager.extend;
|
||||||
|
if (!old.getBasePotionData().isUpgraded() && brewn.getBasePotionData().isUpgraded())
|
||||||
|
exp *= MMOCore.plugin.alchemyManager.upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private Map<PotionEffectType, Double> mapEffectDurations() {
|
||||||
|
// Map<PotionEffectType, Double> map = new HashMap<>();
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * potion level, plus the potion gained duration (max 0 so it does
|
||||||
|
// * not give negative EXP), multiplied by the potion effect weight.
|
||||||
|
// */
|
||||||
|
// brewn.getCustomEffects().forEach(effect -> map.put(effect.getType(),
|
||||||
|
//
|
||||||
|
// (effect.getAmplifier() + 1 + (double) Math.max(0,
|
||||||
|
// effect.getDuration() - getPotionEffect(old,
|
||||||
|
// effect.getType()).orElseGet(() -> new
|
||||||
|
// PotionEffect(PotionEffectType.SPEED, 0, 0)).getDuration()) / 60.)
|
||||||
|
//
|
||||||
|
// * MMOCore.plugin.alchemyManager.getWeight(effect.getType())));
|
||||||
|
//
|
||||||
|
// return map;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private int getTotal(Map<?, Double> map) {
|
||||||
|
// double t = 0;
|
||||||
|
// for (double d : map.values())
|
||||||
|
// t += d;
|
||||||
|
// return (int) t;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private Optional<PotionEffect> getPotionEffect(PotionMeta meta,
|
||||||
|
// PotionEffectType type) {
|
||||||
|
// return meta.getCustomEffects().stream().filter(effect ->
|
||||||
|
// effect.getType() == type).findFirst();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void process(Player player) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate extra exp due to extra effects
|
||||||
|
*/
|
||||||
|
// exp += getTotal(mapEffectDurations());
|
||||||
|
|
||||||
|
getDispenser().giveExperience(PlayerData.get(player), (int) exp, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.inventory.CraftItemEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryAction;
|
||||||
|
|
||||||
|
public class CraftItemExperienceSource extends SpecificExperienceSource<Material> {
|
||||||
|
public final Material material;
|
||||||
|
|
||||||
|
public CraftItemExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<CraftItemExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<CraftItemExperienceSource>() {
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void a(CraftItemEvent event) {
|
||||||
|
if (event.getAction() == InventoryAction.NOTHING ||
|
||||||
|
event.getInventory().getResult() == null) return;
|
||||||
|
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
||||||
|
for (CraftItemExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, event.getInventory().getResult().getType()))
|
||||||
|
source.giveExperience(data, event.getInventory().getResult().getAmount(), event.getInventory().getLocation());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, Material obj) {
|
||||||
|
return material == obj;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class EnchantItemExperienceSource extends ExperienceSource<Void> {
|
||||||
|
private final List<Enchantment> enchants = new ArrayList<>();
|
||||||
|
|
||||||
|
public EnchantItemExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser);
|
||||||
|
|
||||||
|
if (config.contains("enchant"))
|
||||||
|
for (String key : config.getString("enchant").split(","))
|
||||||
|
enchants.add(MythicLib.plugin.getVersion().getWrapper().getEnchantmentFromString(key.toLowerCase().replace("-", "_")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, Void v) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<EnchantItemExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<EnchantItemExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(EnchantItemEvent event) {
|
||||||
|
PlayerData player = PlayerData.get(event.getEnchanter());
|
||||||
|
for (EnchantItemExperienceSource source : getSources())
|
||||||
|
if (source.matches(player, null)) {
|
||||||
|
Map<Enchantment, Integer> ench = new HashMap<>(event.getEnchantsToAdd());
|
||||||
|
|
||||||
|
if (!source.enchants.isEmpty())
|
||||||
|
ench.keySet().removeIf(enchantment -> !source.enchants.contains(enchantment));
|
||||||
|
|
||||||
|
if (ench.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double exp = 0;
|
||||||
|
for (Entry<Enchantment, Integer> entry : ench.entrySet())
|
||||||
|
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
|
||||||
|
getDispenser().giveExperience(player, (int) exp, event.getEnchantBlock().getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.player.PlayerFishEvent;
|
||||||
|
import org.bukkit.event.player.PlayerFishEvent.State;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class FishItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||||
|
private final Material material;
|
||||||
|
|
||||||
|
public FishItemExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<FishItemExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<FishItemExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(PlayerFishEvent event) {
|
||||||
|
if (event.getState() == State.CAUGHT_FISH) {
|
||||||
|
ItemStack caught = ((Item) event.getCaught()).getItemStack();
|
||||||
|
if (caught.hasItemMeta())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerData data = PlayerData.get(event.getPlayer());
|
||||||
|
for (FishItemExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, caught))
|
||||||
|
source.giveExperience(data, caught.getAmount(), event.getHook().getLocation().add(0, 1.0f, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, ItemStack obj) {
|
||||||
|
return obj.getType() == material;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import io.lumine.mythic.lib.api.event.EntityKillEntityEvent;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
|
||||||
|
public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
||||||
|
public final EntityType type;
|
||||||
|
|
||||||
|
public KillMobExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
type = EntityType.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<KillMobExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<KillMobExperienceSource>() {
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void a(EntityKillEntityEvent event) {
|
||||||
|
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
||||||
|
if (event.getTarget().isDead() && event.getEntity() instanceof Player && !event.getEntity().hasMetadata("NPC")
|
||||||
|
&& !event.getTarget().hasMetadata("spawner_spawned")) {
|
||||||
|
PlayerData data = PlayerData.get((Player) event.getEntity());
|
||||||
|
|
||||||
|
for (KillMobExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, event.getTarget()))
|
||||||
|
source.giveExperience(data, 1, event.getTarget().getLocation());
|
||||||
|
}
|
||||||
|
}, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, Entity obj) {
|
||||||
|
return obj.getType() == type;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class MineBlockExperienceSource extends SpecificExperienceSource<Material> {
|
||||||
|
public final Material material;
|
||||||
|
private final boolean silkTouch;
|
||||||
|
private final boolean crop;
|
||||||
|
private final boolean playerPlaced;
|
||||||
|
|
||||||
|
public MineBlockExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
silkTouch = config.getBoolean("silk-touch", true);
|
||||||
|
crop = config.getBoolean("crop", false);
|
||||||
|
playerPlaced = config.getBoolean("player-placed", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<MineBlockExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<MineBlockExperienceSource>() {
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(BlockBreakEvent event) {
|
||||||
|
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerData data = PlayerData.get(event.getPlayer());
|
||||||
|
|
||||||
|
for (MineBlockExperienceSource source : getSources()) {
|
||||||
|
if (source.silkTouch && hasSilkTouch(event.getPlayer().getInventory().getItemInMainHand()))
|
||||||
|
continue;
|
||||||
|
if (source.crop && !MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock()))
|
||||||
|
continue;
|
||||||
|
if ((!source.playerPlaced) && event.getBlock().hasMetadata("player_placed"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (source.matches(data, event.getBlock().getType()))
|
||||||
|
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasSilkTouch(ItemStack item) {
|
||||||
|
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, Material obj) {
|
||||||
|
return material == obj;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
|
||||||
|
public class PlaceBlockExperienceSource extends SpecificExperienceSource<Material> {
|
||||||
|
public final Material material;
|
||||||
|
|
||||||
|
public PlaceBlockExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<PlaceBlockExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<PlaceBlockExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void a(BlockPlaceEvent event) {
|
||||||
|
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerData data = PlayerData.get(event.getPlayer());
|
||||||
|
for (PlaceBlockExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, event.getBlock().getType()))
|
||||||
|
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, Material obj) {
|
||||||
|
return material == obj;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.bukkit.inventory.AnvilInventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.Damageable;
|
||||||
|
|
||||||
|
public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
|
||||||
|
private final Material material;
|
||||||
|
|
||||||
|
public RepairItemExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if material is null, the player can repair ANY material in order to
|
||||||
|
* get experience.
|
||||||
|
*/
|
||||||
|
material = config.contains("type") ? Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_")) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, ItemStack item) {
|
||||||
|
return (material == null || item.getType() == material);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<RepairItemExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<RepairItemExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(InventoryClickEvent event) {
|
||||||
|
if (event.getInventory() != null && event.getInventory().getType() == InventoryType.ANVIL && event.getSlot() == 2) {
|
||||||
|
|
||||||
|
ItemStack item = event.getCurrentItem();
|
||||||
|
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
||||||
|
|
||||||
|
for (RepairItemExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, item)) {
|
||||||
|
|
||||||
|
if (!(event.getInventory() instanceof AnvilInventory))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (((AnvilInventory) event.getInventory()).getRepairCost() > ((Player) event.getWhoClicked()).getLevel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make sure the items can actually be repaired
|
||||||
|
* before getting the amount of durability repaired
|
||||||
|
*/
|
||||||
|
ItemStack old = event.getInventory().getItem(0);
|
||||||
|
if (old == null || old.getType() == Material.AIR)
|
||||||
|
return;
|
||||||
|
if (old.getType().getMaxDurability() < 30 || item.getType().getMaxDurability() < 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!MMOCore.plugin.smithingManager.hasExperience(item.getType()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate exp based on amount of durability which
|
||||||
|
* was repaired, substract damage from old item
|
||||||
|
* durability.
|
||||||
|
*/
|
||||||
|
double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType())
|
||||||
|
* Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100;
|
||||||
|
getDispenser().giveExperience(data, (int) exp, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.BlockCookEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class SmeltItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||||
|
private final Material material;
|
||||||
|
|
||||||
|
public SmeltItemExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser, config);
|
||||||
|
|
||||||
|
config.validate("type");
|
||||||
|
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceSourceManager<SmeltItemExperienceSource> newManager() {
|
||||||
|
return new ExperienceSourceManager<SmeltItemExperienceSource>() {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(BlockCookEvent event) {
|
||||||
|
Optional<Player> player = getNearestPlayer(event.getBlock().getLocation());
|
||||||
|
if (!player.isPresent())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack caught = event.getResult();
|
||||||
|
if (caught.hasItemMeta())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerData data = PlayerData.get(player.get());
|
||||||
|
for (SmeltItemExperienceSource source : getSources())
|
||||||
|
if (source.matches(data, caught))
|
||||||
|
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Player> getNearestPlayer(Location loc) {
|
||||||
|
final Player[] nearby = loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100)
|
||||||
|
.toArray(Player[]::new);
|
||||||
|
Player selected = null;
|
||||||
|
double lastDist = 100;
|
||||||
|
for (Player p : nearby) {
|
||||||
|
double currDist = p.getLocation().distance(loc);
|
||||||
|
if (currDist < lastDist) {
|
||||||
|
lastDist = currDist;
|
||||||
|
selected = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesParameter(PlayerData player, ItemStack obj) {
|
||||||
|
return obj.getType() == material;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source.type;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atrocious API that really needs rewriting
|
||||||
|
*
|
||||||
|
* @author cympe
|
||||||
|
*/
|
||||||
|
public abstract class ExperienceSource<T> {
|
||||||
|
private final ExperienceDispenser dispenser;
|
||||||
|
|
||||||
|
public ExperienceSource(ExperienceDispenser dispenser) {
|
||||||
|
this.dispenser = dispenser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExperienceDispenser getDispenser() {
|
||||||
|
return dispenser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ExperienceSourceManager<?> newManager();
|
||||||
|
|
||||||
|
public boolean matches(PlayerData player, T obj) {
|
||||||
|
return getDispenser().matches(player) && matchesParameter(player, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean matchesParameter(PlayerData player, T obj);
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package net.Indyuce.mmocore.experience.source.type;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public abstract class SpecificExperienceSource<T> extends ExperienceSource<T> {
|
||||||
|
private final RandomAmount amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to register experience sources with SPECIFIC experience outputs.
|
||||||
|
* Other experience sources like ENCHANT have their exp output depend on the
|
||||||
|
* enchanted item. ALCHEMY exp outputs depend on the potion crafted
|
||||||
|
*/
|
||||||
|
public SpecificExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||||
|
super(dispenser);
|
||||||
|
|
||||||
|
config.validate("amount");
|
||||||
|
amount = new RandomAmount(config.getString("amount"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int rollAmount() {
|
||||||
|
return amount.calculateInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when a player needs to gain experience after performing the action
|
||||||
|
* corresponding to this exp source
|
||||||
|
*
|
||||||
|
* @param player Player gaining the exp
|
||||||
|
* @param multiplier Used by the CraftItem experience source, multiplies the exp
|
||||||
|
* earned by a certain factor. When crafting an item, the
|
||||||
|
* multiplier is equal to the amount of items crafted
|
||||||
|
* @param hologramLocation Location used to display the exp hologram
|
||||||
|
*/
|
||||||
|
public void giveExperience(PlayerData player, double multiplier, @Nullable Location hologramLocation) {
|
||||||
|
getDispenser().giveExperience(player, rollAmount() * multiplier, hologramLocation);
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,8 @@ package net.Indyuce.mmocore.gui;
|
|||||||
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Booster;
|
import net.Indyuce.mmocore.experience.Booster;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
|
@ -3,7 +3,7 @@ package net.Indyuce.mmocore.gui;
|
|||||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.quest.Quest;
|
import net.Indyuce.mmocore.api.quest.Quest;
|
||||||
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
||||||
|
@ -4,7 +4,7 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerExpChangeEvent;
|
import org.bukkit.event.player.PlayerExpChangeEvent;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
public class RedirectVanillaExp implements Listener {
|
public class RedirectVanillaExp implements Listener {
|
||||||
|
@ -4,7 +4,7 @@ import io.lumine.mythic.lib.version.VersionSound;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.droptable.dropitem.fishing.FishingDropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.fishing.FishingDropItem;
|
||||||
import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent;
|
import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent;
|
||||||
import net.Indyuce.mmocore.api.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
|
@ -9,7 +9,7 @@ import net.Indyuce.mmocore.MMOCore;
|
|||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||||
|
|
||||||
public class AttributeManager extends MMOManager {
|
public class AttributeManager implements MMOManager {
|
||||||
private final Map<String, PlayerAttribute> map = new HashMap<>();
|
private final Map<String, PlayerAttribute> map = new HashMap<>();
|
||||||
|
|
||||||
public PlayerAttribute get(String id) {
|
public PlayerAttribute get(String id) {
|
||||||
|
@ -26,7 +26,7 @@ import net.Indyuce.mmocore.api.player.profess.event.trigger.ClassChosenEventTrig
|
|||||||
import net.Indyuce.mmocore.api.player.profess.event.trigger.LevelUpEventTrigger;
|
import net.Indyuce.mmocore.api.player.profess.event.trigger.LevelUpEventTrigger;
|
||||||
import net.Indyuce.mmocore.api.player.profess.event.trigger.MultipleLevelUpEventTrigger;
|
import net.Indyuce.mmocore.api.player.profess.event.trigger.MultipleLevelUpEventTrigger;
|
||||||
|
|
||||||
public class ClassManager extends MMOManager {
|
public class ClassManager implements MMOManager {
|
||||||
private final Map<String, PlayerClass> map = new HashMap<>();
|
private final Map<String, PlayerClass> map = new HashMap<>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -22,7 +22,7 @@ import java.util.*;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class CustomBlockManager extends MMOManager {
|
public class CustomBlockManager implements MMOManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registered block infos
|
* Registered block infos
|
||||||
|
@ -16,7 +16,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.droptable.DropTable;
|
import net.Indyuce.mmocore.api.droptable.DropTable;
|
||||||
|
|
||||||
public class DropTableManager extends MMOManager {
|
public class DropTableManager implements MMOManager {
|
||||||
private final Map<String, DropTable> map = new HashMap<>();
|
private final Map<String, DropTable> map = new HashMap<>();
|
||||||
|
|
||||||
public void register(DropTable table) {
|
public void register(DropTable table) {
|
||||||
|
@ -10,7 +10,7 @@ import java.util.logging.Level;
|
|||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.ExpCurve;
|
import net.Indyuce.mmocore.experience.ExpCurve;
|
||||||
|
|
||||||
public class ExperienceManager {
|
public class ExperienceManager {
|
||||||
private final Map<String, ExpCurve> expCurves = new HashMap<>();
|
private final Map<String, ExpCurve> expCurves = new HashMap<>();
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
@ -12,8 +13,7 @@ import com.google.gson.JsonParseException;
|
|||||||
import net.Indyuce.mmocore.api.block.BlockType;
|
import net.Indyuce.mmocore.api.block.BlockType;
|
||||||
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
||||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
|
||||||
import net.Indyuce.mmocore.api.load.DefaultMMOLoader;
|
import net.Indyuce.mmocore.api.load.DefaultMMOLoader;
|
||||||
import net.Indyuce.mmocore.api.load.MMOLoader;
|
import net.Indyuce.mmocore.api.load.MMOLoader;
|
||||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||||
@ -41,8 +41,8 @@ public class MMOLoadManager {
|
|||||||
return load(Objective.class, config, loader -> loader.loadObjective(config, section));
|
return load(Objective.class, config, loader -> loader.loadObjective(config, section));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession) {
|
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||||
return load(ExperienceSource.class, config, loader -> loader.loadExperienceSource(config, profession));
|
return load(ExperienceSource.class, config, loader -> loader.loadExperienceSource(config, dispenser));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Trigger loadTrigger(MMOLineConfig config) {
|
public Trigger loadTrigger(MMOLineConfig config) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.Indyuce.mmocore.manager;
|
package net.Indyuce.mmocore.manager;
|
||||||
|
|
||||||
public abstract class MMOManager {
|
public interface MMOManager {
|
||||||
public abstract void reload();
|
void reload();
|
||||||
|
|
||||||
public abstract void clear();
|
void clear();
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.quest.Quest;
|
import net.Indyuce.mmocore.api.quest.Quest;
|
||||||
|
|
||||||
public class QuestManager extends MMOManager {
|
public class QuestManager implements MMOManager {
|
||||||
private final Map<String, Quest> quests = new LinkedHashMap<>();
|
private final Map<String, Quest> quests = new LinkedHashMap<>();
|
||||||
|
|
||||||
public void load(File file) {
|
public void load(File file) {
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.potion.PotionType;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.manager.MMOManager;
|
import net.Indyuce.mmocore.manager.MMOManager;
|
||||||
|
|
||||||
public class AlchemyManager extends MMOManager {
|
public class AlchemyManager implements MMOManager {
|
||||||
public double splash, lingering, upgrade, extend;
|
public double splash, lingering, upgrade, extend;
|
||||||
|
|
||||||
// private Map<PotionEffectType, Double> custom = new HashMap<>();
|
// private Map<PotionEffectType, Double> custom = new HashMap<>();
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.enchantments.Enchantment;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.manager.MMOManager;
|
import net.Indyuce.mmocore.manager.MMOManager;
|
||||||
|
|
||||||
public class EnchantManager extends MMOManager {
|
public class EnchantManager implements MMOManager {
|
||||||
private final Map<Enchantment, Double> base = new HashMap<>();
|
private final Map<Enchantment, Double> base = new HashMap<>();
|
||||||
|
|
||||||
public void registerBaseExperience(Enchantment enchant, double value) {
|
public void registerBaseExperience(Enchantment enchant, double value) {
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.manager.profession;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
|
|
||||||
public abstract class ExperienceManager<T> implements Listener {
|
|
||||||
private final Set<T> sources = new HashSet<>();
|
|
||||||
|
|
||||||
public ExperienceManager() {
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(T source) {
|
|
||||||
sources.add(source);
|
|
||||||
|
|
||||||
getSources();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<T> getSources() {
|
|
||||||
return sources;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.Indyuce.mmocore.manager.profession;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public abstract class ExperienceSourceManager<T> implements Listener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all active experience sources
|
||||||
|
*/
|
||||||
|
private final Set<T> sources = new HashSet<>();
|
||||||
|
|
||||||
|
public ExperienceSourceManager() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerSource(T source) {
|
||||||
|
sources.add(source);
|
||||||
|
|
||||||
|
getSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<T> getSources() {
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ import net.Indyuce.mmocore.api.droptable.dropitem.fishing.FishingDropItem;
|
|||||||
import net.Indyuce.mmocore.manager.MMOManager;
|
import net.Indyuce.mmocore.manager.MMOManager;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
|
||||||
public class FishingManager extends MMOManager {
|
public class FishingManager implements MMOManager {
|
||||||
private final Set<FishingDropTable> tables = new LinkedHashSet<>();
|
private final Set<FishingDropTable> tables = new LinkedHashSet<>();
|
||||||
|
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
|
@ -11,25 +11,25 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.manager.MMOManager;
|
import net.Indyuce.mmocore.manager.MMOManager;
|
||||||
|
|
||||||
public class ProfessionManager extends MMOManager {
|
public class ProfessionManager implements MMOManager {
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* loaded professions.
|
* Loaded professions.
|
||||||
*/
|
*/
|
||||||
private final Map<String, Profession> professions = new HashMap<>();
|
private final Map<String, Profession> professions = new HashMap<>();
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* saves different experience sources based on experience source type.
|
* Saves different experience sources based on experience source type.
|
||||||
*/
|
*/
|
||||||
private final Map<Class<?>, ExperienceManager<?>> managers = new HashMap<>();
|
private final Map<Class<?>, ExperienceSourceManager<?>> managers = new HashMap<>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> ExperienceManager<T> getManager(Class<T> t) {
|
public <T> ExperienceSourceManager<T> getManager(Class<T> t) {
|
||||||
return (ExperienceManager<T>) managers.get(t);
|
return (ExperienceSourceManager<T>) managers.get(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -38,7 +38,7 @@ public class ProfessionManager extends MMOManager {
|
|||||||
|
|
||||||
if (!managers.containsKey(path))
|
if (!managers.containsKey(path))
|
||||||
managers.put(path, source.newManager());
|
managers.put(path, source.newManager());
|
||||||
getManager(path).register(source);
|
getManager(path).registerSource(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(Profession profession) {
|
public void register(Profession profession) {
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.Material;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.manager.MMOManager;
|
import net.Indyuce.mmocore.manager.MMOManager;
|
||||||
|
|
||||||
public class SmithingManager extends MMOManager {
|
public class SmithingManager implements MMOManager {
|
||||||
private final Map<Material, Double> base = new HashMap<>();
|
private final Map<Material, Double> base = new HashMap<>();
|
||||||
|
|
||||||
public void registerBaseExperience(Material material, double value) {
|
public void registerBaseExperience(Material material, double value) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.Indyuce.mmocore.manager.social;
|
package net.Indyuce.mmocore.manager.social;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.experience.Booster;
|
import net.Indyuce.mmocore.experience.Booster;
|
||||||
import net.Indyuce.mmocore.api.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -15,7 +15,7 @@ import java.util.Set;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
public class PartyManager extends MMOManager {
|
public class PartyManager implements MMOManager {
|
||||||
private final Set<Party> parties = new HashSet<>();
|
private final Set<Party> parties = new HashSet<>();
|
||||||
private final Map<StatType, StatModifier> buffs = new HashMap<>();
|
private final Map<StatType, StatModifier> buffs = new HashMap<>();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user