MMOCore now takes in stats from ML

This commit is contained in:
Indyuce 2022-05-28 15:26:22 +02:00
parent 0648079232
commit eed3502029
25 changed files with 403 additions and 296 deletions

View File

@ -10,7 +10,6 @@ import net.Indyuce.mmocore.api.PlayerActionBar;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.AttributeModifier; import net.Indyuce.mmocore.api.player.attribute.AttributeModifier;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.util.debug.DebugMode; import net.Indyuce.mmocore.api.util.debug.DebugMode;
import net.Indyuce.mmocore.command.*; import net.Indyuce.mmocore.command.*;
import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener; import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener;
@ -77,6 +76,7 @@ public class MMOCore extends LuminePlugin {
public final LootChestManager lootChests = new LootChestManager(); public final LootChestManager lootChests = new LootChestManager();
public final MMOLoadManager loadManager = new MMOLoadManager(); public final MMOLoadManager loadManager = new MMOLoadManager();
public final RestrictionManager restrictionManager = new RestrictionManager(); public final RestrictionManager restrictionManager = new RestrictionManager();
public final StatManager statManager = new StatManager();
@Deprecated @Deprecated
public final SkillTreeManager skillTreeManager = new SkillTreeManager(); public final SkillTreeManager skillTreeManager = new SkillTreeManager();
@ -385,6 +385,7 @@ public class MMOCore extends LuminePlugin {
configManager = new ConfigManager(); configManager = new ConfigManager();
statManager.initialize(clearBefore);
if (clearBefore) if (clearBefore)
MythicLib.plugin.getSkills().initialize(true); MythicLib.plugin.getSkills().initialize(true);
skillManager.initialize(clearBefore); skillManager.initialize(clearBefore);
@ -414,8 +415,6 @@ public class MMOCore extends LuminePlugin {
if (getConfig().isConfigurationSection("action-bar")) if (getConfig().isConfigurationSection("action-bar"))
actionBarManager.reload(getConfig().getConfigurationSection("action-bar")); actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));
StatType.load();
if (clearBefore) if (clearBefore)
PlayerData.getAll().forEach(PlayerData::update); PlayerData.getAll().forEach(PlayerData::update);
} }

View File

@ -1,18 +1,17 @@
package net.Indyuce.mmocore.api; package net.Indyuce.mmocore.api;
import java.text.DecimalFormat; import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import net.Indyuce.mmocore.MMOCore; import java.text.DecimalFormat;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import io.lumine.mythic.lib.MythicLib;
public class PlayerActionBar extends BukkitRunnable { public class PlayerActionBar extends BukkitRunnable {
boolean initialized = false; boolean initialized = false;
@ -41,17 +40,17 @@ public class PlayerActionBar extends BukkitRunnable {
data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(), data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(),
MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format) MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format)
.replace("{health}", digit.format(data.getPlayer().getHealth())) .replace("{health}", digit.format(data.getPlayer().getHealth()))
.replace("{max_health}", "" + StatType.MAX_HEALTH.format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())) .replace("{max_health}", StatInfo.valueOf("MAX_HEALTH").format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()))
.replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon()) .replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon())
.replace("{mana}", digit.format(data.getMana())) .replace("{mana}", digit.format(data.getMana()))
.replace("{max_mana}", "" + StatType.MAX_MANA.format(data.getStats().getStat(StatType.MAX_MANA))) .replace("{max_mana}", StatInfo.valueOf("MAX_MANA").format(data.getStats().getStat("MAX_MANA")))
.replace("{stamina}", digit.format(data.getStamina())) .replace("{stamina}", digit.format(data.getStamina()))
.replace("{max_stamina}", "" + StatType.MAX_STAMINA.format(data.getStats().getStat(StatType.MAX_STAMINA))) .replace("{max_stamina}", StatInfo.valueOf("MAX_STAMINA").format(data.getStats().getStat("MAX_STAMINA")))
.replace("{stellium}", digit.format(data.getStellium())) .replace("{stellium}", digit.format(data.getStellium()))
.replace("{max_stellium}", "" + StatType.MAX_STELLIUM.format(data.getStats().getStat(StatType.MAX_STELLIUM))) .replace("{max_stellium}", StatInfo.valueOf("MAX_STELLIUM").format(data.getStats().getStat("MAX_STELLIUM")))
.replace("{class}", data.getProfess().getName()) .replace("{class}", data.getProfess().getName())
.replace("{xp}", "" + data.getExperience()) .replace("{xp}", "" + data.getExperience())
.replace("{armor}", "" + StatType.ARMOR.format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue())) .replace("{armor}", StatInfo.valueOf("ARMOR").format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue()))
.replace("{level}", "" + data.getLevel()) .replace("{level}", "" + data.getLevel())
.replace("{name}", data.getPlayer().getDisplayName()))))); .replace("{name}", data.getPlayer().getDisplayName())))));
} }

View File

@ -17,7 +17,6 @@ import net.Indyuce.mmocore.api.player.profess.Subclass;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.social.FriendRequest; import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.api.player.stats.PlayerStats; import net.Indyuce.mmocore.api.player.stats.PlayerStats;
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.Closable; import net.Indyuce.mmocore.api.util.Closable;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@ -542,7 +541,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
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("ADDITIONAL_EXPERIENCE") / 100;
// Splitting exp through party members // Splitting exp through party members
AbstractParty party = getParty(); AbstractParty party = getParty();
@ -615,7 +614,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveMana(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { public void giveMana(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat(StatType.MAX_MANA); double max = getStats().getStat("MAX_MANA");
double newest = Math.max(0, Math.min(mana + amount, max)); double newest = Math.max(0, Math.min(mana + amount, max));
if (mana == newest) if (mana == newest)
return; return;
@ -640,7 +639,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveStamina(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { public void giveStamina(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat(StatType.MAX_STAMINA); double max = getStats().getStat("MAX_STAMINA");
double newest = Math.max(0, Math.min(stamina + amount, max)); double newest = Math.max(0, Math.min(stamina + amount, max));
if (stamina == newest) if (stamina == newest)
return; return;
@ -665,7 +664,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveStellium(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { public void giveStellium(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat(StatType.MAX_STELLIUM); double max = getStats().getStat("MAX_STELLIUM");
double newest = Math.max(0, Math.min(stellium + amount, max)); double newest = Math.max(0, Math.min(stellium + amount, max));
if (stellium == newest) if (stellium == newest)
return; return;
@ -700,15 +699,15 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
public void setMana(double amount) { public void setMana(double amount) {
mana = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_MANA))); mana = Math.max(0, Math.min(amount, getStats().getStat("MAX_MANA")));
} }
public void setStamina(double amount) { public void setStamina(double amount) {
stamina = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STAMINA))); stamina = Math.max(0, Math.min(amount, getStats().getStat("MAX_STAMINA")));
} }
public void setStellium(double amount) { public void setStellium(double amount) {
stellium = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STELLIUM))); stellium = Math.max(0, Math.min(amount, getStats().getStat("MAX_STELLIUM")));
} }
public boolean isFullyLoaded() { public boolean isFullyLoaded() {

View File

@ -25,8 +25,8 @@ public class PlayerAttribute implements ExperienceObject {
private final ExperienceTable expTable; private final ExperienceTable expTable;
/** /**
* Used to store stats using StatType, but attributes also need to access * All buffs granted by an attribute. These are normalized and
* non basic MMOCore stats hence the string maps keys * must be multiplied by the player level first
*/ */
private final Set<StatModifier> buffs = new HashSet<>(); private final Set<StatModifier> buffs = new HashSet<>();

View File

@ -13,17 +13,17 @@ 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.ResourceRegeneration; import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration;
import net.Indyuce.mmocore.api.player.stats.StatType;
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.experience.EXPSource; import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.experience.ExpCurve; import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject; import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.player.playerclass.ClassTrigger; import net.Indyuce.mmocore.player.playerclass.ClassTrigger;
import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; import net.Indyuce.mmocore.player.playerclass.ClassTriggerType;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -51,7 +51,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final ExpCurve expCurve; private final ExpCurve expCurve;
private final ExperienceTable expTable; private final ExperienceTable expTable;
private final Map<StatType, LinearValue> stats = new HashMap<>(); private final Map<String, LinearValue> stats = new HashMap<>();
private final Map<String, ClassSkill> skills = new LinkedHashMap<>(); private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
private final List<Subclass> subclasses = new ArrayList<>(); private final List<Subclass> subclasses = new ArrayList<>();
@ -124,7 +124,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
if (config.contains("attributes")) if (config.contains("attributes"))
for (String key : config.getConfigurationSection("attributes").getKeys(false)) for (String key : config.getConfigurationSection("attributes").getKeys(false))
try { try {
stats.put(StatType.valueOf(key.toUpperCase().replace("-", "_")), stats.put(UtilityMethods.enumName(key),
new LinearValue(config.getConfigurationSection("attributes." + key))); new LinearValue(config.getConfigurationSection("attributes." + key)));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load stat info '" + key + "' from class '" MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load stat info '" + key + "' from class '"
@ -331,16 +331,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return eventTriggers.get(name); return eventTriggers.get(name);
} }
@Deprecated public void setDefaultStatFormula(String type, LinearValue value) {
public void setStat(StatType type, double base, double perLevel) { stats.put(UtilityMethods.enumName(type), value);
setStat(type, new LinearValue(base, perLevel));
} }
public void setStat(StatType type, LinearValue value) { public double calculateStat(String stat, int level) {
stats.put(type, value);
}
public double calculateStat(StatType stat, int level) {
return getStatInfo(stat).calculate(level); return getStatInfo(stat).calculate(level);
} }
@ -396,8 +391,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return skills.values(); return skills.values();
} }
private LinearValue getStatInfo(StatType type) { @NotNull
return stats.containsKey(type) ? stats.get(type) : type.getDefault(); private LinearValue getStatInfo(String stat) {
LinearValue found = stats.get(stat);
return found == null ? StatInfo.valueOf(stat).getDefaultFormula() : found;
} }
@Override @Override

View File

@ -3,7 +3,6 @@ package net.Indyuce.mmocore.api.player.profess.resource;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption; import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger; import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
@ -20,27 +19,27 @@ public enum PlayerResource {
(data, amount) -> data.getPlayer().setHealth(amount)), (data, amount) -> data.getPlayer().setHealth(amount)),
MANA(PlayerData::getMana, MANA(PlayerData::getMana,
data -> data.getStats().getStat(StatType.MAX_MANA), data -> data.getStats().getStat("MAX_MANA"),
(data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveMana(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveMana(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setMana(amount)), (data, amount) -> data.setMana(amount)),
STAMINA(PlayerData::getStamina, STAMINA(PlayerData::getStamina,
data -> data.getStats().getStat(StatType.MAX_STAMINA), data -> data.getStats().getStat("MAX_STAMINA"),
(data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveStamina(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStamina(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setStamina(amount)), (data, amount) -> data.setStamina(amount)),
STELLIUM(PlayerData::getStellium, STELLIUM(PlayerData::getStellium,
data -> data.getStats().getStat(StatType.MAX_STELLIUM), data -> data.getStats().getStat("MAX_STELLIUM"),
(data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveStellium(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStellium(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setStellium(amount)); (data, amount) -> data.setStellium(amount));
private final StatType regenStat, maxRegenStat; private final String regenStat, maxRegenStat;
private final ClassOption offCombatRegen; private final ClassOption offCombatRegen;
private final Function<PlayerData, Double> current, max; private final Function<PlayerData, Double> current, max;
private final BiConsumer<PlayerData, Double> regen; private final BiConsumer<PlayerData, Double> regen;
@ -54,8 +53,8 @@ public enum PlayerResource {
BiConsumer<PlayerData, Double> give, BiConsumer<PlayerData, Double> give,
BiConsumer<PlayerData, Double> take, BiConsumer<PlayerData, Double> take,
BiConsumer<PlayerData, Double> set) { BiConsumer<PlayerData, Double> set) {
this.regenStat = StatType.valueOf(name() + "_REGENERATION"); this.regenStat = name() + "_REGENERATION";
this.maxRegenStat = StatType.valueOf("MAX_" + name() + "_REGENERATION"); this.maxRegenStat = "MAX_" + name() + "_REGENERATION";
this.offCombatRegen = ClassOption.valueOf("OFF_COMBAT_" + name() + "_REGEN"); this.offCombatRegen = ClassOption.valueOf("OFF_COMBAT_" + name() + "_REGEN");
this.current = current; this.current = current;
this.max = max; this.max = max;
@ -68,14 +67,14 @@ public enum PlayerResource {
/** /**
* @return Stat which corresponds to flat resource regeneration * @return Stat which corresponds to flat resource regeneration
*/ */
public StatType getRegenStat() { public String getRegenStat() {
return regenStat; return regenStat;
} }
/** /**
* @return Stat which corresponds to resource regeneration scaling with the player's max health * @return Stat which corresponds to resource regeneration scaling with the player's max health
*/ */
public StatType getMaxRegenStat() { public String getMaxRegenStat() {
return maxRegenStat; return maxRegenStat;
} }

View File

@ -8,11 +8,8 @@ import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.ClassSkill;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
public class PlayerStats { public class PlayerStats {
private final PlayerData data; private final PlayerData data;
@ -34,6 +31,7 @@ public class PlayerStats {
return data.getMMOPlayerData().getStatMap(); return data.getMMOPlayerData().getStatMap();
} }
@Deprecated
public StatInstance getInstance(StatType stat) { public StatInstance getInstance(StatType stat) {
return getMap().getInstance(stat.name()); return getMap().getInstance(stat.name());
} }
@ -42,35 +40,26 @@ public class PlayerStats {
return getMap().getInstance(stat); return getMap().getInstance(stat);
} }
/** public double getStat(String stat) {
* Allows for stat type enum to have dynamic professions.
* ID FORMAT: STAT_TYPE_HERE_PROFESSION_HERE
*
* @param type the type of stat
* @param profession the stat's specific permission
* @return instance of found stat
* @author Ehhthan
*/
@NotNull
public StatInstance getInstance(StatType type, @Nullable Profession profession) {
if (profession == null)
return getInstance(type);
else {
String id = (type.name() + '_' + profession.getId()).replace('-', '_').replace(' ', '_').toUpperCase(Locale.ROOT);
return getInstance(id);
}
}
/*
* applies relative attributes on the base stat too
*/
public double getStat(StatType stat) {
return getInstance(stat).getTotal(); return getInstance(stat).getTotal();
} }
public double getBase(StatType stat) { /**
return data.getProfess().calculateStat(stat, * MMOCore base stat value differs from the on in MythicLib.
stat.hasProfession() ? data.getCollectionSkills().getLevel(stat.getProfession()) : data.getLevel()); * <p>
* MythicLib: the base stat value is only defined for stats
* which are based on vanilla player attributes. It corresponds
* to the stat amount any player has with NO attribute modifier whatsoever.
* <p>
* MMOCore: the base stat value corresponds to the stat amount
* the player CLASS grants. It can be similar or equal to the one
* in MMOCore but it really is completely different.
*
* @return MMOCore base stat value
*/
public double getBase(String stat) {
Profession profession = StatInfo.valueOf(stat).profession;
return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession));
} }
/** /**
@ -81,7 +70,7 @@ public class PlayerStats {
* see {@link PlayerData#update()} for more info * see {@link PlayerData#update()} for more info
*/ */
public synchronized void updateStats() { public synchronized void updateStats() {
for (StatType stat : StatType.values()) { for (StatType stat : StatType.values()) { // TODO fix
StatInstance instance = getMap().getInstance(stat.name()); StatInstance instance = getMap().getInstance(stat.name());
StatInstance.ModifierPacket packet = instance.newPacket(); StatInstance.ModifierPacket packet = instance.newPacket();
@ -89,7 +78,7 @@ public class PlayerStats {
packet.removeIf(str -> str.equals("mmocoreClass")); packet.removeIf(str -> str.equals("mmocoreClass"));
// Add newest one // Add newest one
double total = getBase(stat) - instance.getBase(); double total = getBase(stat.name()) - instance.getBase();
if (total != 0) if (total != 0)
packet.addModifier(new StatModifier("mmocoreClass", stat.name(), total, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER)); packet.addModifier(new StatModifier("mmocoreClass", stat.name(), total, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));

View File

@ -1,14 +1,14 @@
package net.Indyuce.mmocore.api.player.stats; package net.Indyuce.mmocore.api.player.stats;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import org.bukkit.configuration.file.FileConfiguration; import net.Indyuce.mmocore.player.stats.StatInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat; import java.util.Objects;
@Deprecated
public enum StatType { public enum StatType {
// Vanilla stats // Vanilla stats
@ -87,17 +87,17 @@ public enum StatType {
/** /**
* Reduces amount of tugs needed to fish * Reduces amount of tugs needed to fish
*/ */
FISHING_STRENGTH("fishing"), FISHING_STRENGTH,
/** /**
* Chance of instant success when fishing * Chance of instant success when fishing
*/ */
CRITICAL_FISHING_CHANCE("fishing"), CRITICAL_FISHING_CHANCE,
/** /**
* Chance of crit fishing failure * Chance of crit fishing failure
*/ */
CRITICAL_FISHING_FAILURE_CHANCE("fishing"), CRITICAL_FISHING_FAILURE_CHANCE,
/** /**
* Chance of dropping more minerals when mining. * Chance of dropping more minerals when mining.
@ -114,49 +114,35 @@ public enum StatType {
*/ */
LUCK_OF_THE_FIELD; LUCK_OF_THE_FIELD;
private String profession; @Deprecated
private LinearValue defaultInfo;
private DecimalFormat format;
StatType() {
// Completely custom stat
}
@SuppressWarnings("SameParameterValue")
StatType(String profession) {
this.profession = profession;
}
public String getProfession() { public String getProfession() {
return profession; return findProfession().getId();
} }
@Deprecated
@Nullable
public Profession findProfession() { public Profession findProfession() {
return MMOCore.plugin.professionManager.get(profession); return StatInfo.valueOf(name()).profession;
} }
@Deprecated
public boolean hasProfession() { public boolean hasProfession() {
return profession != null; return findProfession() != null;
} }
@Deprecated
@NotNull
public LinearValue getDefault() { public LinearValue getDefault() {
return defaultInfo; return StatInfo.valueOf(name()).getDefaultFormula();
} }
@Deprecated
public boolean matches(Profession profession) { public boolean matches(Profession profession) {
return this.profession != null && this.profession.equals(profession.getId()); return Objects.equals(findProfession(), profession);
} }
@Deprecated
public String format(double value) { public String format(double value) {
return format.format(value); return StatInfo.valueOf(name()).format(value);
}
public static void load() {
FileConfiguration config = new ConfigFile("stats").getConfig();
for (StatType stat : values()) {
stat.defaultInfo = config.contains("default." + stat.name()) ? new LinearValue(config.getConfigurationSection("default." + stat.name())) : new LinearValue(0, 0);
stat.format = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.contains("decimal-format." + stat.name()) ? config.getString("decimal-format." + stat.name()) : "0.#");
}
} }
} }

View File

@ -110,4 +110,16 @@ public class LinearValue {
return value; return value;
} }
@Override
public String toString() {
return "LinearValue{" +
"base=" + base +
", perLevel=" + perLevel +
", min=" + min +
", max=" + max +
", hasmin=" + hasmin +
", hasmax=" + hasmax +
'}';
}
} }

View File

@ -1,11 +1,11 @@
package net.Indyuce.mmocore.command.rpg.debug; package net.Indyuce.mmocore.command.rpg.debug;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.StatInstance; import io.lumine.mythic.lib.api.stat.StatInstance;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.command.api.CommandTreeNode; import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter; import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -15,10 +15,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
public StatModifiersCommandTreeNode(CommandTreeNode parent) { public StatModifiersCommandTreeNode(CommandTreeNode parent) {
super(parent, "statmods"); super(parent, "statmods");
addParameter(new Parameter("<stat>", (explorer, list) -> { addParameter(new Parameter("<stat>", (explorer, list) -> list.add("STAT_ID")));
for (StatType stat : StatType.values())
list.add(stat.name());
}));
} }
@Override @Override
@ -32,15 +29,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
} }
PlayerData data = PlayerData.get((Player) sender); PlayerData data = PlayerData.get((Player) sender);
StatType stat; StatInstance instance = data.getStats().getInstance(UtilityMethods.enumName(args[2]));
try {
stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_"));
} catch (IllegalArgumentException exception) {
sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + ".");
return CommandResult.FAILURE;
}
StatInstance instance = data.getStats().getInstance(stat);
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):"); sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) { for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key); StatModifier mod = instance.getModifier(key);

View File

@ -1,23 +1,19 @@
package net.Indyuce.mmocore.command.rpg.debug; package net.Indyuce.mmocore.command.rpg.debug;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.player.stats.StatInfo;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
public class StatValueCommandTreeNode extends CommandTreeNode { public class StatValueCommandTreeNode extends CommandTreeNode {
public StatValueCommandTreeNode(CommandTreeNode parent) { public StatValueCommandTreeNode(CommandTreeNode parent) {
super(parent, "statvalue"); super(parent, "statvalue");
addParameter(new Parameter("<stat>", (explorer, list) -> { addParameter(new Parameter("<stat>", (explorer, list) -> list.add("STAT_ID")));
for (StatType stat : StatType.values())
list.add(stat.name());
}));
addParameter(new Parameter("(formatted)", (explorer, list) -> list.add("true")));
} }
@Override @Override
@ -31,20 +27,9 @@ public class StatValueCommandTreeNode extends CommandTreeNode {
} }
PlayerData data = PlayerData.get((Player) sender); PlayerData data = PlayerData.get((Player) sender);
StatType stat; StatInfo stat = StatInfo.valueOf(UtilityMethods.enumName(args[2]));
try { sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name + ChatColor.WHITE + "): "
stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_")); + ChatColor.GREEN + data.getStats().getStat(stat.name));
} catch (IllegalArgumentException exception) {
sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + ".");
return CommandResult.FAILURE;
}
if (args.length > 3 && args[3].equals("true"))
sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): "
+ ChatColor.GREEN + stat.format(data.getStats().getStat(stat)) + ChatColor.WHITE + " *");
else
sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): "
+ ChatColor.GREEN + data.getStats().getStat(stat));
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }

View File

@ -5,7 +5,7 @@ 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.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.api.quest.PlayerQuests;
import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
@ -72,11 +72,11 @@ public class RPGPlaceholders extends PlaceholderExpansion {
} }
else if (identifier.equals("health") && player.isOnline()) { else if (identifier.equals("health") && player.isOnline()) {
return StatType.MAX_HEALTH.format(player.getPlayer().getHealth()); return StatInfo.valueOf("MAX_HEALTH").format(player.getPlayer().getHealth());
} }
else if (identifier.equals("max_health") && player.isOnline()) { else if (identifier.equals("max_health") && player.isOnline()) {
return StatType.MAX_HEALTH.format(player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); return StatInfo.valueOf("MAX_HEALTH").format(player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
} }
else if (identifier.equals("health_bar") && player.isOnline()) { else if (identifier.equals("health_bar") && player.isOnline()) {
@ -153,7 +153,7 @@ public class RPGPlaceholders extends PlaceholderExpansion {
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana()); return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
else if (identifier.equals("mana_bar")) { else if (identifier.equals("mana_bar")) {
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat(StatType.MAX_MANA)); return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
} }
else if (identifier.startsWith("exp_multiplier_")) { else if (identifier.startsWith("exp_multiplier_")) {
@ -173,7 +173,7 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (identifier.equals("stamina_bar")) { else if (identifier.equals("stamina_bar")) {
StringBuilder format = new StringBuilder(); StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat(StatType.MAX_STAMINA); double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA");
for (double j = 1; j < 20; j++) for (double j = 1; j < 20; j++)
format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty) : ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
@ -182,8 +182,8 @@ public class RPGPlaceholders extends PlaceholderExpansion {
} }
else if (identifier.startsWith("stat_")) { else if (identifier.startsWith("stat_")) {
StatType type = StatType.valueOf(identifier.substring(5).toUpperCase()); StatInfo info = StatInfo.valueOf(identifier.substring(5).toUpperCase());
return type == null ? "Invalid Stat" : type.format(playerData.getStats().getStat(type)); return info.format(playerData.getStats().getStat(info.name));
} }
else if (identifier.equals("stellium")) else if (identifier.equals("stellium"))
@ -191,7 +191,7 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (identifier.equals("stellium_bar")) { else if (identifier.equals("stellium_bar")) {
StringBuilder format = new StringBuilder(); StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat(StatType.MAX_STELLIUM); double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
for (double j = 1; j < 20; j++) for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare); format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
return format.toString(); return format.toString();

View File

@ -4,13 +4,13 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
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.SoundEvent; import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent; import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
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.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -168,7 +168,7 @@ public class PlayerProfessions {
value = MMOCore.plugin.boosterManager.calculateExp(profession, value); value = MMOCore.plugin.boosterManager.calculateExp(profession, value);
// Adds functionality for additional experience per profession. // Adds functionality for additional experience per profession.
value *= 1 + playerData.getStats().getInstance(StatType.ADDITIONAL_EXPERIENCE, profession).getTotal() / 100; value *= 1 + playerData.getStats().getInstance("ADDITIONAL_EXPERIENCE_" + UtilityMethods.enumName(profession.getId())).getTotal() / 100;
// Display hologram // Display hologram
if (hologramLocation != null) if (hologramLocation != null)

View File

@ -13,6 +13,7 @@ import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.manager.SoundManager; import net.Indyuce.mmocore.manager.SoundManager;
import net.Indyuce.mmocore.player.stats.StatInfo;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -66,8 +67,9 @@ public class AttributeView extends EditableInventory {
holders.register("current", total); holders.register("current", total);
holders.register("attribute_points", inv.getPlayerData().getAttributePoints()); holders.register("attribute_points", inv.getPlayerData().getAttributePoints());
attribute.getBuffs().forEach(buff -> { attribute.getBuffs().forEach(buff -> {
holders.register("buff_" + buff.getStat().toLowerCase(), buff.getValue()); StatInfo info = StatInfo.valueOf(buff.getStat());
holders.register("total_" + buff.getStat().toLowerCase(), buff.multiply(total).getValue()); holders.register("buff_" + buff.getStat().toLowerCase(), info.format(buff.getValue()));
holders.register("total_" + buff.getStat().toLowerCase(), info.format(buff.multiply(total).getValue()));
}); });
return holders; return holders;
} }

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmocore.gui; package net.Indyuce.mmocore.gui;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
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.experience.Booster;
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.player.stats.StatInfo;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat; import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import net.Indyuce.mmocore.experience.Booster;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.gui.api.EditableInventory; import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.InventoryItem;
@ -18,10 +19,13 @@ import net.Indyuce.mmocore.party.AbstractParty;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import java.util.Objects;
public class PlayerStats extends EditableInventory { public class PlayerStats extends EditableInventory {
public PlayerStats() { public PlayerStats() {
super("player-stats"); super("player-stats");
@ -78,7 +82,7 @@ public class PlayerStats extends EditableInventory {
Placeholders holders = new Placeholders(); Placeholders holders = new Placeholders();
net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats(); net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
double ratio = (double) inv.getPlayerData().getCollectionSkills().getExperience(profession) double ratio = inv.getPlayerData().getCollectionSkills().getExperience(profession)
/ (double) inv.getPlayerData().getCollectionSkills().getLevelUpExperience(profession); / (double) inv.getPlayerData().getCollectionSkills().getLevelUpExperience(profession);
String bar = "" + ChatColor.BOLD; String bar = "" + ChatColor.BOLD;
@ -91,9 +95,9 @@ public class PlayerStats extends EditableInventory {
holders.register("level", "" + inv.getPlayerData().getCollectionSkills().getLevel(profession)); holders.register("level", "" + inv.getPlayerData().getCollectionSkills().getLevel(profession));
holders.register("xp", inv.getPlayerData().getCollectionSkills().getExperience(profession)); holders.register("xp", inv.getPlayerData().getCollectionSkills().getExperience(profession));
holders.register("percent", decimal.format(ratio * 100)); holders.register("percent", decimal.format(ratio * 100));
for (StatType stat : StatType.values()) for (StatInfo stat : MMOCore.plugin.statManager.getLoaded())
if (stat.matches(profession)) if (Objects.equals(stat.profession, profession))
holders.register(stat.name().toLowerCase(), stat.format(stats.getStat(stat))); holders.register(stat.name.toLowerCase(), stat.format(stats.getStat(stat.name)));
return holders; return holders;
} }
@ -113,21 +117,35 @@ public class PlayerStats extends EditableInventory {
@Override @Override
public Placeholders getPlaceholders(GeneratedInventory inv, int n) { public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
return new Placeholders() {
final net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats(); public String apply(Player player, String str) {
Placeholders holders = new Placeholders(); while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) {
String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}"));
String replaced;
for (StatType stat : StatType.values()) { if (holder.endsWith("_base")) {
double base = stats.getBase(stat), total = stats.getStat(stat), extra = total - base; StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
holders.register(stat.name().toLowerCase(), stat.format(total)); replaced = info.format(stats.getBase(info.name));
holders.register(stat.name().toLowerCase() + "_base", stat.format(base)); } else if (holder.endsWith("_extra")) {
holders.register(stat.name().toLowerCase() + "_extra", stat.format(extra)); StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
replaced = info.format(stats.getStat(info.name) - stats.getBase(info.name));
} else if (holder.startsWith("attribute_")) {
PlayerAttribute attr = MMOCore.plugin.attributeManager.get(holder.substring(10).replace("_", "-").toLowerCase());
replaced = String.valueOf(inv.getPlayerData().getAttributes().getAttribute(attr));
} else {
StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder));
replaced = info.format(stats.getStat(info.name));
} }
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) str = str.replace("{" + holder + "}", replaced);
holders.register("attribute_" + attribute.getId().replace("-", "_"), inv.getPlayerData().getAttributes().getAttribute(attribute)); }
return holders; // External placeholders
return MMOCore.plugin.placeholderParser.parse(player, str);
}
};
} }
}; };

View File

@ -4,7 +4,6 @@ import io.lumine.mythic.lib.version.VersionSound;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent; import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent;
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.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.loot.LootBuilder;
@ -84,7 +83,7 @@ public class FishingListener implements Listener {
this.playerData = PlayerData.get(this.player = player); this.playerData = PlayerData.get(this.player = player);
this.hook = hook; this.hook = hook;
this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat(StatType.FISHING_STRENGTH) / 100)); this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat("FISHING_STRENGTH") / 100));
this.experienceDropped = caught.rollExperience(); this.experienceDropped = caught.rollExperience();
fishing.add(player.getUniqueId()); fishing.add(player.getUniqueId());
@ -148,7 +147,7 @@ public class FishingListener implements Listener {
return; return;
} }
if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_CHANCE) / 100) if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_CHANCE") / 100)
setCriticalFish(); setCriticalFish();
// Check if enough pulls; if not, wait till the next fish event // Check if enough pulls; if not, wait till the next fish event
@ -165,7 +164,7 @@ public class FishingListener implements Listener {
(mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1); (mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1);
// Critical fishing failure // Critical fishing failure
if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_FAILURE_CHANCE) / 100) { if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_FAILURE_CHANCE") / 100) {
player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5)); player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5));
hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08);
return; return;

View File

@ -1,7 +1,8 @@
package net.Indyuce.mmocore.listener.profession; package net.Indyuce.mmocore.listener.profession;
import java.util.Random; import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -11,10 +12,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent; import java.util.Random;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import io.lumine.mythic.lib.MythicLib;
public class PlayerCollectStats implements Listener { public class PlayerCollectStats implements Listener {
private static final Random random = new Random(); private static final Random random = new Random();
@ -23,26 +21,26 @@ public class PlayerCollectStats implements Listener {
public void a(CustomBlockMineEvent event) { public void a(CustomBlockMineEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
// give haste if right enchant // Give haste if right enchant
double h = event.getData().getStats().getStat(StatType.GATHERING_HASTE); double h = event.getData().getStats().getStat("GATHERING_HASTE");
if (h > 0 && random.nextDouble() < h * .045) { if (h > 0 && random.nextDouble() < h * .045) {
new SmallParticleEffect(player, Particle.SPELL_INSTANT); new SmallParticleEffect(player, Particle.SPELL_INSTANT);
player.removePotionEffect(PotionEffectType.FAST_DIGGING); player.removePotionEffect(PotionEffectType.FAST_DIGGING);
player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (10 * h), (int) (1 + h / 7))); player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (10 * h), (int) (1 + h / 7)));
} }
// drop more items if fortune enchant // Drop more items if fortune enchant
double f = event.getData().getStats().getStat(StatType.FORTUNE); double f = event.getData().getStats().getStat("FORTUNE");
if (f > 0 && random.nextDouble() < f * .045) { if (f > 0 && random.nextDouble() < f * .045) {
int a = (int) (1.5 * Math.sqrt(f / 1.1)); int a = (int) (1.5 * Math.sqrt(f / 1.1));
for (ItemStack item : event.getDrops()) for (ItemStack item : event.getDrops())
item.setAmount(item.getAmount() + a); item.setAmount(item.getAmount() + a);
} }
if(MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock())) if (MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock())) {
{
// drop more items if fortune enchant // Drop more CROP items
double l = event.getData().getStats().getStat(StatType.LUCK_OF_THE_FIELD); double l = event.getData().getStats().getStat("LUCK_OF_THE_FIELD");
if (l > 0 && random.nextDouble() < l * .045) { if (l > 0 && random.nextDouble() < l * .045) {
int a = (int) (1.5 * Math.sqrt(l / 1.1)); int a = (int) (1.5 * Math.sqrt(l / 1.1));
Location loc = event.getBlock().getLocation().add(.5, .1, .5); Location loc = event.getBlock().getLocation().add(.5, .1, .5);

View File

@ -4,7 +4,6 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.LootChestSpawnEvent; import net.Indyuce.mmocore.api.event.LootChestSpawnEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.loot.LootBuilder;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -125,7 +124,7 @@ public class LootChestRegion {
*/ */
@NotNull @NotNull
public ChestTier rollTier(PlayerData player) { public ChestTier rollTier(PlayerData player) {
double chance = player.getStats().getStat(StatType.CHANCE) * MMOCore.plugin.configManager.lootChestsChanceWeight; double chance = player.getStats().getStat("CHANCE") * MMOCore.plugin.configManager.lootChestsChanceWeight;
double sum = 0; double sum = 0;
for (ChestTier tier : tiers) for (ChestTier tier : tiers)

View File

@ -3,7 +3,6 @@ package net.Indyuce.mmocore.loot.droptable.dropitem;
import java.util.Random; import java.util.Random;
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.loot.LootBuilder; import net.Indyuce.mmocore.loot.LootBuilder;
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;
@ -40,7 +39,7 @@ public abstract class DropItem {
* If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one. * If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one.
*/ */
public boolean rollChance(PlayerData player) { public boolean rollChance(PlayerData player) {
return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance; return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat("CHANCE"))) < chance;
} }
public abstract void collect(LootBuilder builder); public abstract void collect(LootBuilder builder);

View File

@ -0,0 +1,71 @@
package net.Indyuce.mmocore.manager;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.Profession;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class StatManager implements MMOCoreManager {
private final Map<String, StatInfo> loaded = new HashMap<>();
@Override
public void initialize(boolean clearBefore) {
if (clearBefore)
loaded.clear();
FileConfiguration config = new ConfigFile("stats").getConfig();
// Read decimal formats
for (String key : config.getConfigurationSection("decimal-format").getKeys(false))
registerDecimalFormat(key, MythicLib.plugin.getMMOConfig().newDecimalFormat(config.getString("decimal-format." + key)));
// Read default formulas
for (String key : config.getConfigurationSection("default").getKeys(false))
registerDefaultFormula(key, new LinearValue(config.getConfigurationSection("default." + key)));
}
public Collection<StatInfo> getLoaded() {
return loaded.values();
}
@Nullable
public StatInfo getInfo(String stat) {
return loaded.get(stat);
}
public void registerProfession(String stat, Profession profession) {
compute(stat).profession = profession;
}
public void registerDefaultFormula(String stat, LinearValue defaultFormula) {
compute(stat).defaultInfo = defaultFormula;
}
public void registerDecimalFormat(String stat, DecimalFormat format) {
compute(stat).format = format;
}
/**
* @return A stat info for the specified stat. If it doesn't
* exist when method is called, it is registered into the map
*/
@NotNull
private StatInfo compute(String stat) {
StatInfo found = loaded.get(stat);
if (found != null)
return found;
StatInfo newInfo = new StatInfo(stat);
loaded.put(stat, newInfo);
return newInfo;
}
}

View File

@ -9,7 +9,6 @@ import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.PlayerDataManager; import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table; import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table;
@ -35,6 +34,13 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
try { try {
MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'..."); MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'...");
// Initialize custom resources
if (!data.hasUsedTemporaryData()) {
data.setMana(data.getStats().getStat("MAX_MANA"));
data.setStamina(data.getStats().getStat("MAX_STAMINA"));
data.setStellium(data.getStats().getStat("MAX_STELLIUM"));
}
if (!result.next()) { if (!result.next()) {
data.setLevel(getDefaultData().getLevel()); data.setLevel(getDefaultData().getLevel());
data.setClassPoints(getDefaultData().getClassPoints()); data.setClassPoints(getDefaultData().getClassPoints());
@ -44,12 +50,6 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
data.setExperience(0); data.setExperience(0);
data.getQuestData().updateBossBar(); data.getQuestData().updateBossBar();
if (!data.hasUsedTemporaryData()) {
data.setMana(data.getStats().getStat(StatType.MAX_MANA));
data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA));
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
}
data.setFullyLoaded(); data.setFullyLoaded();
MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found."); MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
return; return;
@ -69,12 +69,6 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt())); json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
} }
if (!data.hasUsedTemporaryData()) {
data.setMana(data.getStats().getStat(StatType.MAX_MANA));
data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA));
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
}
if (!isEmpty(result.getString("guild"))) { if (!isEmpty(result.getString("guild"))) {
Guild guild = provider.getGuildManager().getGuild(result.getString("guild")); Guild guild = provider.getGuildManager().getGuild(result.getString("guild"));
data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null); data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null);

View File

@ -6,7 +6,6 @@ import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.DataProvider; import net.Indyuce.mmocore.manager.data.DataProvider;
import net.Indyuce.mmocore.manager.data.PlayerDataManager; import net.Indyuce.mmocore.manager.data.PlayerDataManager;
@ -41,9 +40,9 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
data.setClass(MMOCore.plugin.classManager.get(config.getString("class"))); data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
if (!data.hasUsedTemporaryData()) { if (!data.hasUsedTemporaryData()) {
data.setMana(data.getStats().getStat(StatType.MAX_MANA)); data.setMana(data.getStats().getStat("MAX_MANA"));
data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA)); data.setStamina(data.getStats().getStat("MAX_STAMINA"));
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM)); data.setStellium(data.getStats().getStat("MAX_STELLIUM"));
} }
if (config.contains("guild")) { if (config.contains("guild")) {

View File

@ -3,7 +3,6 @@ package net.Indyuce.mmocore.manager.profession;
import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
@ -31,6 +30,11 @@ public class FishingManager extends SpecificProfessionManager {
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "Could not load fishing drop table " + key + ": " + exception.getMessage()); MMOCore.log(Level.WARNING, "Could not load fishing drop table " + key + ": " + exception.getMessage());
} }
// Link fishing stats to this profession
MMOCore.plugin.statManager.registerProfession("FISHING_STRENGTH", getLinkedProfession());
MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_CHANCE", getLinkedProfession());
MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_FAILURE_CHANCE", getLinkedProfession());
} }
public FishingDropTable calculateDropTable(Entity entity) { public FishingDropTable calculateDropTable(Entity entity) {
@ -46,7 +50,6 @@ public class FishingManager extends SpecificProfessionManager {
public static class FishingDropTable { public static class FishingDropTable {
private final Set<Condition> conditions = new HashSet<>(); private final Set<Condition> conditions = new HashSet<>();
private final List<FishingDropItem> items = new ArrayList<>(); private final List<FishingDropItem> items = new ArrayList<>();
private double maxWeight = 0;
public FishingDropTable(ConfigurationSection section) { public FishingDropTable(ConfigurationSection section) {
Validate.notNull(section, "Could not load config"); Validate.notNull(section, "Could not load config");
@ -72,7 +75,6 @@ public class FishingManager extends SpecificProfessionManager {
try { try {
FishingDropItem dropItem = new FishingDropItem(new MMOLineConfig(str)); FishingDropItem dropItem = new FishingDropItem(new MMOLineConfig(str));
items.add(dropItem); items.add(dropItem);
maxWeight += dropItem.getItem().getWeight();
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage()); "Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage());
@ -93,11 +95,13 @@ public class FishingManager extends SpecificProfessionManager {
} }
/** /**
* The Fishing Drop Item is calculated randomly bu the chance stat will make * The chance stat will make low weight items more
* low weight items more likely to be caught. * likely to be chosen by the algorithm
*
* @return Randomly computed fishing drop item
*/ */
public FishingDropItem getRandomItem(PlayerData player) { public FishingDropItem getRandomItem(PlayerData player) {
double chance = player.getStats().getStat(StatType.CHANCE); double chance = player.getStats().getStat("CHANCE");
//chance=0 ->the tier.chance remains the same //chance=0 ->the tier.chance remains the same
//chance ->+inf -> the tier.chance becomes the same for everyone, uniform law //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law

View File

@ -1,8 +1,8 @@
package net.Indyuce.mmocore.manager.social; package net.Indyuce.mmocore.manager.social;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.manager.MMOCoreManager; import net.Indyuce.mmocore.manager.MMOCoreManager;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -26,8 +26,7 @@ public class PartyManager implements MMOCoreManager {
if (config != null) if (config != null)
for (String key : config.getKeys(false)) for (String key : config.getKeys(false))
try { try {
StatType stat = StatType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_")); buffs.add(new StatModifier("mmocoreParty", UtilityMethods.enumName(key), config.getString(key)));
buffs.add(new StatModifier("mmocoreParty", stat.name(), config.getString(key)));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage()); MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage());
} }

View File

@ -0,0 +1,71 @@
package net.Indyuce.mmocore.player.stats;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.Profession;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
import java.util.Objects;
/**
* @author Jules
* @impl MMOCore used to have a giant enum of all the stat types
* which is now incompatible with MythicLib because the MMO plugins
* now have completely OPEN to edition numeric stat registries
*/
public class StatInfo {
public final String name;
/**
* Profession linked to that stat. Stats which have a profession linked to
* them do NOT scale on the main player level but rather on that specific
* profession level
*/
public Profession profession;
/**
* Default formula for the stat
*/
public LinearValue defaultInfo;
/**
* How that stat displays anywhere in GUIs
*/
public DecimalFormat format;
private static final DecimalFormat DEFAULT_DECIMAL_FORMAT = new DecimalFormat("0.#");
public StatInfo(String name) {
this.name = name;
}
@NotNull
public String format(double d) {
return (format == null ? DEFAULT_DECIMAL_FORMAT : format).format(d);
}
@NotNull
public LinearValue getDefaultFormula() {
return defaultInfo == null ? LinearValue.ZERO : defaultInfo;
}
@NotNull
public static StatInfo valueOf(String str) {
StatInfo found = MMOCore.plugin.statManager.getInfo(str);
return found == null ? new StatInfo(str) : found;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StatInfo statInfo = (StatInfo) o;
return name.equals(statInfo.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}