New max resource regen stats

This commit is contained in:
Indyuce 2021-10-30 12:29:35 +02:00
parent fb80ed2ce1
commit 717b2cb1d9
6 changed files with 339 additions and 339 deletions

View File

@ -90,11 +90,6 @@ public class MMOCore extends LuminePlugin {
public final MMOLoadManager loadManager = new MMOLoadManager(); public final MMOLoadManager loadManager = new MMOLoadManager();
public boolean healthRegenFlat;
public boolean manaRegenFlat;
public boolean staminaRegenFlat;
public boolean stelliumRegenFlat;
public boolean shouldDebugSQL = false; public boolean shouldDebugSQL = false;
public MMOCore() { public MMOCore() {
@ -146,13 +141,6 @@ public class MMOCore extends LuminePlugin {
if (getConfig().isConfigurationSection("default-playerdata")) if (getConfig().isConfigurationSection("default-playerdata"))
dataProvider.getDataManager().loadDefaultData(getConfig().getConfigurationSection("default-playerdata")); dataProvider.getDataManager().loadDefaultData(getConfig().getConfigurationSection("default-playerdata"));
if (getConfig().isConfigurationSection("stat-regen-flat")) {
healthRegenFlat = getConfig().getBoolean("stat-regen-flat.health", true);
manaRegenFlat = getConfig().getBoolean("stat-regen-flat.mana", true);
staminaRegenFlat = getConfig().getBoolean("stat-regen-flat.stamina", true);
stelliumRegenFlat = getConfig().getBoolean("stat-regen-flat.stellium", true);
}
if (Bukkit.getPluginManager().getPlugin("Vault") != null) economy = new VaultEconomy(); if (Bukkit.getPluginManager().getPlugin("Vault") != null) economy = new VaultEconomy();
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
@ -190,32 +178,8 @@ public class MMOCore extends LuminePlugin {
if (player.isOnline() && !player.getPlayer().isDead()) if (player.isOnline() && !player.getPlayer().isDead())
for (PlayerResource resource : PlayerResource.values()) { for (PlayerResource resource : PlayerResource.values()) {
double regenAmount = player.getProfess().getHandler(resource).getRegen(player); double regenAmount = player.getProfess().getHandler(resource).getRegen(player);
switch (resource) { if (regenAmount != 0)
case HEALTH: resource.regen(player, regenAmount);
if (healthRegenFlat && regenAmount != 0)
resource.regen(player, regenAmount);
else if (!healthRegenFlat && regenAmount * player.getStats().getStat(StatType.HEALTH_REGENERATION) != 0)
resource.regen(player, player.getStats().getStat(StatType.MAX_HEALTH) * regenAmount);
break;
case MANA:
if (manaRegenFlat && regenAmount != 0)
resource.regen(player, regenAmount);
else if (!manaRegenFlat && regenAmount * player.getStats().getStat(StatType.MANA_REGENERATION) != 0)
resource.regen(player, player.getStats().getStat(StatType.MAX_MANA) * regenAmount);
break;
case STAMINA:
if (staminaRegenFlat && regenAmount != 0)
resource.regen(player, regenAmount);
else if (!staminaRegenFlat && regenAmount * player.getStats().getStat(StatType.STAMINA_REGENERATION) != 0)
resource.regen(player, player.getStats().getStat(StatType.MAX_STAMINA) * regenAmount);
break;
case STELLIUM:
if (stelliumRegenFlat && regenAmount != 0)
resource.regen(player, regenAmount);
else if (!stelliumRegenFlat && regenAmount * player.getStats().getStat(StatType.STELLIUM_REGENERATION) != 0)
resource.regen(player, player.getStats().getStat(StatType.MAX_STELLIUM) * regenAmount);
break;
}
} }
} }
}.runTaskTimer(MMOCore.plugin, 100, 20); }.runTaskTimer(MMOCore.plugin, 100, 20);

View File

@ -10,7 +10,7 @@ import net.Indyuce.mmocore.MMOCore;
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.ResourceRegeneration;
import net.Indyuce.mmocore.api.player.stats.StatType; 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;
@ -47,7 +47,7 @@ public class PlayerClass extends PostLoadObject {
private final Map<String, SkillInfo> skills = new LinkedHashMap<>(); private final Map<String, SkillInfo> skills = new LinkedHashMap<>();
private final List<Subclass> subclasses = new ArrayList<>(); private final List<Subclass> subclasses = new ArrayList<>();
private final Map<PlayerResource, ResourceHandler> resourceHandlers = new HashMap<>(); private final Map<PlayerResource, ResourceRegeneration> resourceHandlers = new HashMap<>();
private final Map<String, EventTrigger> eventTriggers = new HashMap<>(); private final Map<String, EventTrigger> eventTriggers = new HashMap<>();
private final CastingParticle castParticle; private final CastingParticle castParticle;
@ -142,7 +142,7 @@ public class PlayerClass extends PostLoadObject {
String format = key.toLowerCase().replace("_", "-").replace(" ", "-"); String format = key.toLowerCase().replace("_", "-").replace(" ", "-");
eventTriggers.put(format, new EventTrigger(format, config.getStringList("triggers." + key))); eventTriggers.put(format, new EventTrigger(format, config.getStringList("triggers." + key)));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] " + exception.getMessage()); MMOCore.log(Level.WARNING, "Could not load trigger '" + key + "' from class '" + id + "':" + exception.getMessage());
} }
} }
@ -153,15 +153,15 @@ public class PlayerClass extends PostLoadObject {
for (PlayerResource resource : PlayerResource.values()) { for (PlayerResource resource : PlayerResource.values()) {
if (config.isConfigurationSection("resource." + resource.name().toLowerCase())) if (config.isConfigurationSection("resource." + resource.name().toLowerCase()))
try { try {
resourceHandlers.put(resource, new ResourceHandler(resource, resourceHandlers.put(resource, new ResourceRegeneration(resource,
config.getConfigurationSection("resource." + resource.name().toLowerCase()))); config.getConfigurationSection("resource." + resource.name().toLowerCase())));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] Could not load special resource regen for " MMOCore.log(Level.WARNING, "Could not load special " + resource.name().toLowerCase() + " regen from class '"
+ resource.name() + ": " + exception.getMessage()); + id + "': " + exception.getMessage());
resourceHandlers.put(resource, new ResourceHandler(resource)); resourceHandlers.put(resource, new ResourceRegeneration(resource));
} }
else else
resourceHandlers.put(resource, new ResourceHandler(resource)); resourceHandlers.put(resource, new ResourceRegeneration(resource));
} }
} }
@ -185,7 +185,7 @@ public class PlayerClass extends PostLoadObject {
setOption(ClassOption.DEFAULT, false); setOption(ClassOption.DEFAULT, false);
for (PlayerResource resource : PlayerResource.values()) for (PlayerResource resource : PlayerResource.values())
resourceHandlers.put(resource, new ResourceHandler(resource)); resourceHandlers.put(resource, new ResourceRegeneration(resource));
} }
@Override @Override
@ -215,7 +215,7 @@ public class PlayerClass extends PostLoadObject {
return manaDisplay; return manaDisplay;
} }
public ResourceHandler getHandler(PlayerResource resource) { public ResourceRegeneration getHandler(PlayerResource resource) {
return resourceHandlers.get(resource); return resourceHandlers.get(resource);
} }

View File

@ -12,115 +12,118 @@ import java.util.function.Function;
public enum PlayerResource { public enum PlayerResource {
HEALTH(StatType.HEALTH_REGENERATION, ClassOption.OFF_COMBAT_HEALTH_REGEN, HEALTH(data -> data.getPlayer().getHealth(),
(data) -> data.getPlayer().getHealth(), data -> data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(),
data -> data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(), (data, amount) -> data.heal(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.heal(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.heal(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.heal(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.heal(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.heal(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.getPlayer().setHealth(amount)),
(data, amount) -> data.getPlayer().setHealth(amount)),
MANA(StatType.MANA_REGENERATION, ClassOption.OFF_COMBAT_MANA_REGEN, MANA(PlayerData::getMana,
PlayerData::getMana, data -> data.getStats().getStat(StatType.MAX_MANA),
data -> data.getStats().getStat(StatType.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(StatType.STAMINA_REGENERATION, ClassOption.OFF_COMBAT_STAMINA_REGEN, STAMINA(PlayerData::getStamina,
PlayerData::getStamina, data -> data.getStats().getStat(StatType.MAX_STAMINA),
data -> data.getStats().getStat(StatType.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(StatType.STELLIUM_REGENERATION, ClassOption.OFF_COMBAT_STELLIUM_REGEN, STELLIUM(PlayerData::getStellium,
PlayerData::getStellium, data -> data.getStats().getStat(StatType.MAX_STELLIUM),
data -> data.getStats().getStat(StatType.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; private final StatType 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;
// Used for MMOCore commands // Used for MMOCore commands
private final BiConsumer<PlayerData, Double> set, give, take; private final BiConsumer<PlayerData, Double> set, give, take;
PlayerResource(StatType regenStat, ClassOption offCombatRegen, PlayerResource(Function<PlayerData, Double> current,
Function<PlayerData, Double> current, Function<PlayerData, Double> max,
Function<PlayerData, Double> max, BiConsumer<PlayerData, Double> regen,
BiConsumer<PlayerData, Double> regen, 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 = regenStat; this.maxRegenStat = StatType.valueOf("MAX_" + name() + "_REGENERATION");
this.offCombatRegen = offCombatRegen; this.offCombatRegen = ClassOption.valueOf("OFF_COMBAT_" + name() + "_REGEN");
this.current = current; this.current = current;
this.max = max; this.max = max;
this.regen = regen; this.regen = regen;
this.give = give; this.give = give;
this.take = take; this.take = take;
this.set = set; this.set = set;
} }
/** /**
* @return Stat which corresponds to resource regeneration * @return Stat which corresponds to flat resource regeneration
*/ */
public StatType getRegenStat() { public StatType getRegenStat() {
return regenStat; return regenStat;
} }
/** /**
* @return Class option which determines whether or not resource should be * @return Stat which corresponds to resource regeneration scaling with the player's max health
* regenerated off combat only */
*/ public StatType getMaxRegenStat() {
public ClassOption getOffCombatRegen() { return maxRegenStat;
return offCombatRegen; }
}
/** /**
* @return Current resource of the given player * @return Class option which determines whether or not resource should be
*/ * regenerated off combat only
public double getCurrent(PlayerData player) { */
return current.apply(player); public ClassOption getOffCombatRegen() {
} return offCombatRegen;
}
/** /**
* @return Max amount of that resource of the given player * @return Current resource of the given player
*/ */
public double getMax(PlayerData player) { public double getCurrent(PlayerData player) {
return max.apply(player); return current.apply(player);
} }
/** /**
* Regens a player resource. Whatever resource, a bukkit event is triggered * @return Max amount of that resource of the given player
* */
* @param player Player to regen public double getMax(PlayerData player) {
* @param amount Amount to regen return max.apply(player);
*/ }
public void regen(PlayerData player, double amount) {
regen.accept(player, amount);
}
/** /**
* Used by MMOCore admin commands here: {@link net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode} * Regens a player resource. Whatever resource, a bukkit event is triggered
*/ *
public BiConsumer<PlayerData, Double> getConsumer(ManaTrigger.Operation operation) { * @param player Player to regen
switch (operation) { * @param amount Amount to regen
case SET: */
return set; public void regen(PlayerData player, double amount) {
case TAKE: regen.accept(player, amount);
return take; }
case GIVE:
return give; /**
default: * Used by MMOCore admin commands here: {@link net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode}
throw new IllegalArgumentException("Operation cannot be null"); */
} public BiConsumer<PlayerData, Double> getConsumer(ManaTrigger.Operation operation) {
} switch (operation) {
case SET:
return set;
case TAKE:
return take;
case GIVE:
return give;
default:
throw new IllegalArgumentException("Operation cannot be null");
}
}
} }

View File

@ -1,100 +0,0 @@
package net.Indyuce.mmocore.api.player.profess.resource;
import java.util.function.BiFunction;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
public class ResourceHandler {
/**
* Resource should only regenerate when the player is out of combat
*/
private final boolean offCombatOnly;
/**
* Percentage of scaling which the player regenerates every second
*/
private final LinearValue scalar;
/**
* Whether the resource regeneration scales on missing or max resource. if
* TYPE is null, then there is no special regeneration.
*/
private final HandlerType type;
private final PlayerResource resource;
/**
* Used when there is no special resource regeneration
*/
public ResourceHandler(PlayerResource resource) {
this(resource, null, null, false);
}
public ResourceHandler(PlayerResource resource, ConfigurationSection config) {
this.resource = resource;
offCombatOnly = config.getBoolean("off-combat");
Validate.isTrue(config.contains("type"), "Could not find resource regen scaling type");
type = HandlerType.valueOf(config.getString("type").toUpperCase());
Validate.notNull(config.getConfigurationSection("value"), "Could not find resource regen value config section");
scalar = new LinearValue(config.getConfigurationSection("value"));
}
public ResourceHandler(PlayerResource resource, HandlerType type, LinearValue scalar, boolean offCombatOnly) {
this.resource = resource;
this.type = type;
this.scalar = scalar;
this.offCombatOnly = offCombatOnly;
}
/**
* Apply regeneration formulas: first calculates base resource regen due to
* the player stats and then apply the special resource regeneration due to
* the player class
*
* @param player
* Player regenerating
* @return The amount of resource which should be regenerated EVERY SECOND
*/
public double getRegen(PlayerData player) {
double d = 0;
// base resource regeneration = value of the corresponding regen stat
if (!player.isInCombat() || !player.getProfess().hasOption(resource.getOffCombatRegen()))
d += player.getStats().getStat(resource.getRegenStat());
// extra resource regeneration based on CLASS, scales on LEVEL
if (type != null && (!player.isInCombat() || !offCombatOnly))
d = this.scalar.calculate(player.getLevel()) / 100 * type.getScaling(player, resource);
return d;
}
public enum HandlerType {
/**
* Resource regeneration scales on max resource
*/
MAX((player, resource) -> resource.getMax(player)),
/**
* Resource regeneration scales on missing resource
*/
MISSING((player, resource) -> resource.getMax(player) - resource.getCurrent(player));
private final BiFunction<PlayerData, PlayerResource, Double> calculation;
HandlerType(BiFunction<PlayerData, PlayerResource, Double> calculation) {
this.calculation = calculation;
}
public double getScaling(PlayerData player, PlayerResource resource) {
return calculation.apply(player, resource);
}
}
}

View File

@ -0,0 +1,103 @@
package net.Indyuce.mmocore.api.player.profess.resource;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import java.util.function.BiFunction;
public class ResourceRegeneration {
/**
* Resource should only regenerate when the player is out of combat
*/
private final boolean offCombatOnly;
/**
* Percentage of scaling which the player regenerates every second
*/
private final LinearValue scalar;
/**
* Whether the resource regeneration scales on missing or max resource. if
* TYPE is null, then there is no special regeneration.
*/
private final HandlerType type;
private final PlayerResource resource;
/**
* Used when there is no special resource regeneration
*/
public ResourceRegeneration(PlayerResource resource) {
this(resource, null, null, false);
}
public ResourceRegeneration(PlayerResource resource, ConfigurationSection config) {
this.resource = resource;
offCombatOnly = config.getBoolean("off-combat");
Validate.isTrue(config.contains("type"), "Could not find resource regen scaling type");
type = HandlerType.valueOf(config.getString("type").toUpperCase());
Validate.notNull(config.getConfigurationSection("value"), "Could not find resource regen value config section");
scalar = new LinearValue(config.getConfigurationSection("value"));
}
public ResourceRegeneration(PlayerResource resource, HandlerType type, LinearValue scalar, boolean offCombatOnly) {
this.resource = resource;
this.type = type;
this.scalar = scalar;
this.offCombatOnly = offCombatOnly;
}
/**
* Apply regeneration formulas: first calculates base resource regen due to
* the player stats and then apply the special resource regeneration due to
* the player class
*
* @param player Player regenerating
* @return The amount of resource which should be regenerated EVERY SECOND
*/
public double getRegen(PlayerData player) {
double d = 0;
if (!player.isInCombat() || !player.getProfess().hasOption(resource.getOffCombatRegen())) {
// Flat resource regeneration
d += player.getStats().getStat(resource.getRegenStat());
// Component which scales with max resource
d += player.getStats().getStat(resource.getMaxRegenStat()) / 100 * resource.getMax(player);
}
// Special resource regeneration
if (type != null && (!player.isInCombat() || !offCombatOnly))
d += this.scalar.calculate(player.getLevel()) / 100 * type.getScaling(player, resource);
return d;
}
public enum HandlerType {
/**
* Resource regeneration scales on max resource
*/
MAX((player, resource) -> resource.getMax(player)),
/**
* Resource regeneration scales on missing resource
*/
MISSING((player, resource) -> resource.getMax(player) - resource.getCurrent(player));
private final BiFunction<PlayerData, PlayerResource, Double> calculation;
HandlerType(BiFunction<PlayerData, PlayerResource, Double> calculation) {
this.calculation = calculation;
}
public double getScaling(PlayerData player, PlayerResource resource) {
return calculation.apply(player, resource);
}
}
}

View File

@ -1,130 +1,160 @@
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.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.api.ConfigFile;
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 net.Indyuce.mmocore.experience.Profession;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import java.text.DecimalFormat; import java.text.DecimalFormat;
public enum StatType { public enum StatType {
ATTACK_DAMAGE, // Vanilla stats
ATTACK_SPEED, ATTACK_DAMAGE,
MAX_HEALTH, ATTACK_SPEED,
HEALTH_REGENERATION, MAX_HEALTH,
HEALTH_REGENERATION,
MAX_HEALTH_REGENERATION,
MOVEMENT_SPEED, // Misc
SPEED_MALUS_REDUCTION, MOVEMENT_SPEED,
KNOCKBACK_RESISTANCE, SPEED_MALUS_REDUCTION,
KNOCKBACK_RESISTANCE,
MAX_MANA, // Mana
MAX_STAMINA, MAX_MANA,
MAX_STELLIUM, MANA_REGENERATION,
MANA_REGENERATION, MAX_MANA_REGENERATION,
STAMINA_REGENERATION,
STELLIUM_REGENERATION,
ARMOR, // Stamina
ARMOR_TOUGHNESS, MAX_STAMINA,
STAMINA_REGENERATION,
MAX_STAMINA_REGENERATION,
CRITICAL_STRIKE_CHANCE, // Stellium
CRITICAL_STRIKE_POWER, MAX_STELLIUM,
SKILL_CRITICAL_STRIKE_CHANCE, STELLIUM_REGENERATION,
SKILL_CRITICAL_STRIKE_POWER, MAX_STELLIUM_REGENERATION,
BLOCK_POWER, // Vanilla armor stats
BLOCK_RATING, ARMOR,
BLOCK_COOLDOWN_REDUCTION, ARMOR_TOUGHNESS,
DODGE_RATING,
DODGE_COOLDOWN_REDUCTION,
PARRY_RATING,
PARRY_COOLDOWN_REDUCTION,
ADDITIONAL_EXPERIENCE, // Critical strikes
COOLDOWN_REDUCTION, CRITICAL_STRIKE_CHANCE,
CRITICAL_STRIKE_POWER,
SKILL_CRITICAL_STRIKE_CHANCE,
SKILL_CRITICAL_STRIKE_POWER,
MAGIC_DAMAGE, // Mitigation
PHYSICAL_DAMAGE, DEFENSE,
PROJECTILE_DAMAGE, BLOCK_POWER,
WEAPON_DAMAGE, BLOCK_RATING,
SKILL_DAMAGE, BLOCK_COOLDOWN_REDUCTION,
UNDEAD_DAMAGE, DODGE_RATING,
DODGE_COOLDOWN_REDUCTION,
PARRY_RATING,
PARRY_COOLDOWN_REDUCTION,
PVP_DAMAGE, // Utility
PVE_DAMAGE, ADDITIONAL_EXPERIENCE,
COOLDOWN_REDUCTION,
DEFENSE, // Damage-type based stats
DAMAGE_REDUCTION, MAGIC_DAMAGE,
MAGIC_DAMAGE_REDUCTION, PHYSICAL_DAMAGE,
PHYSICAL_DAMAGE_REDUCTION, PROJECTILE_DAMAGE,
PROJECTILE_DAMAGE_REDUCTION, WEAPON_DAMAGE,
WEAPON_DAMAGE_REDUCTION, SKILL_DAMAGE,
SKILL_DAMAGE_REDUCTION, UNDEAD_DAMAGE,
// reduces amount of tugs needed to fish // Misc damage stats
FISHING_STRENGTH("fishing"), PVP_DAMAGE,
PVE_DAMAGE,
// chance of instant success when fishing // Damage reduction stats
CRITICAL_FISHING_CHANCE("fishing"), DAMAGE_REDUCTION,
MAGIC_DAMAGE_REDUCTION,
PHYSICAL_DAMAGE_REDUCTION,
PROJECTILE_DAMAGE_REDUCTION,
WEAPON_DAMAGE_REDUCTION,
SKILL_DAMAGE_REDUCTION,
// chance of crit fishing failure /**
CRITICAL_FISHING_FAILURE_CHANCE("fishing"), * Reduces amount of tugs needed to fish
*/
FISHING_STRENGTH("fishing"),
// chance of dropping more minerals when mining. /**
FORTUNE, * Chance of instant success when fishing
*/
CRITICAL_FISHING_CHANCE("fishing"),
// get haste when mining blocks. /**
GATHERING_HASTE, * Chance of crit fishing failure
*/
CRITICAL_FISHING_FAILURE_CHANCE("fishing"),
// chance of getting more crops when farming /**
LUCK_OF_THE_FIELD; * Chance of dropping more minerals when mining.
*/
FORTUNE,
private String profession; /**
* Get haste when mining blocks.
*/
GATHERING_HASTE,
private LinearValue defaultInfo; /**
private DecimalFormat format; * Chance of getting more crops when farming
*/
LUCK_OF_THE_FIELD;
StatType() { private String profession;
// completely custom stat.
}
@SuppressWarnings("SameParameterValue") private LinearValue defaultInfo;
StatType(String profession) { private DecimalFormat format;
this.profession = profession;
}
public String getProfession() { StatType() {
return profession; // Completely custom stat
} }
public Profession findProfession() { @SuppressWarnings("SameParameterValue")
return MMOCore.plugin.professionManager.get(profession); StatType(String profession) {
} this.profession = profession;
}
public boolean hasProfession() { public String getProfession() {
return profession != null; return profession;
} }
public LinearValue getDefault() { public Profession findProfession() {
return defaultInfo; return MMOCore.plugin.professionManager.get(profession);
} }
public boolean matches(Profession profession) { public boolean hasProfession() {
return this.profession != null && this.profession.equals(profession.getId()); return profession != null;
} }
public String format(double value) { public LinearValue getDefault() {
return format.format(value); return defaultInfo;
} }
public static void load() { public boolean matches(Profession profession) {
FileConfiguration config = new ConfigFile("stats").getConfig(); return this.profession != null && this.profession.equals(profession.getId());
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().newFormat(config.contains("decimal-format." + stat.name()) ? config.getString("decimal-format." + stat.name()) : "0.#"); public String format(double value) {
} return format.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().newFormat(config.contains("decimal-format." + stat.name()) ? config.getString("decimal-format." + stat.name()) : "0.#");
}
}
} }