Custom EXP Curves

This commit is contained in:
Aria Sangarin 2020-03-10 14:45:49 +01:00
parent d63093d627
commit 80bfe6faba
19 changed files with 119 additions and 33 deletions

View File

@ -15,7 +15,7 @@ import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.mmogroup.mmolib.MMOLib; import net.mmogroup.mmolib.MMOLib;
public class Profession { public class Profession {
private final String id, name; private final String id, name, expCurve;
private final LinearValue experience; private final LinearValue experience;
@ -31,6 +31,7 @@ public class Profession {
this.name = config.getString("name"); this.name = config.getString("name");
Validate.notNull(name, "Could not load name"); Validate.notNull(name, "Could not load name");
expCurve = config.getString("exp-curve", "levels");
experience = new LinearValue(config.getConfigurationSection("experience")); experience = new LinearValue(config.getConfigurationSection("experience"));
if (config.contains("exp-sources")) if (config.contains("exp-sources"))
@ -109,6 +110,10 @@ public class Profession {
return name; return name;
} }
public String getEXPCurve() {
return expCurve;
}
public int calculateExperience(int x) { public int calculateExperience(int x) {
return (int) experience.calculate(x); return (int) experience.calculate(x);
} }

View File

@ -218,13 +218,13 @@ public class PlayerData extends OfflinePlayerData {
public void giveLevels(int value) { public void giveLevels(int value) {
int total = 0; int total = 0;
while (value-- > 0) while (value-- > 0)
total += MMOCore.plugin.configManager.getNeededExperience(getLevel() + value + 1); total += MMOCore.plugin.configManager.getNeededExperience(getLevel() + value + 1, profess);
giveExperience(total); giveExperience(total);
} }
public void setExperience(int value) { public void setExperience(int value) {
experience = Math.max(0, value); experience = Math.max(0, value);
refreshVanillaExp(MMOCore.plugin.configManager.getNeededExperience(getLevel() + 1)); refreshVanillaExp(MMOCore.plugin.configManager.getNeededExperience(getLevel() + 1, profess));
} }
public void refreshVanillaExp(float needed) { public void refreshVanillaExp(float needed) {
@ -409,7 +409,7 @@ public class PlayerData extends OfflinePlayerData {
int needed; int needed;
boolean check = false; boolean check = false;
while (experience >= (needed = MMOCore.plugin.configManager.getNeededExperience(getLevel() + 1))) { while (experience >= (needed = MMOCore.plugin.configManager.getNeededExperience(getLevel() + 1, profess))) {
if (hasReachedMaxLevel()) { if (hasReachedMaxLevel()) {
experience = 0; experience = 0;

View File

@ -101,7 +101,7 @@ public class Professions {
public void giveLevels(Profession profession, int value) { public void giveLevels(Profession profession, int value) {
int total = 0, level = getLevel(profession); int total = 0, level = getLevel(profession);
while (value-- > 0) while (value-- > 0)
total += MMOCore.plugin.configManager.getNeededExperience(level + value + 1); total += MMOCore.plugin.configManager.getNeededExperience(level + value + 1, profession);
giveExperience(profession, total); giveExperience(profession, total);
} }
@ -121,11 +121,11 @@ public class Professions {
int needed, exp, level; int needed, exp, level;
boolean check = false; boolean check = false;
while ((exp = this.exp.get(profession.getId())) >= (needed = MMOCore.plugin.configManager.getNeededExperience((level = getLevel(profession)) + 1))) { while ((exp = this.exp.get(profession.getId())) >= (needed = MMOCore.plugin.configManager.getNeededExperience((level = getLevel(profession)) + 1, profession))) {
this.exp.put(profession.getId(), exp - needed); this.exp.put(profession.getId(), exp - needed);
this.level.put(profession.getId(), level + 1); this.level.put(profession.getId(), level + 1);
check = true; check = true;
playerData.giveExperience((int) profession.getExperience().calculate(level)); playerData.giveExperience((int) profession.getExperience().calculate(level), null);
Bukkit.getPluginManager().callEvent(new PlayerLevelUpEvent(playerData, profession, level + 1)); Bukkit.getPluginManager().callEvent(new PlayerLevelUpEvent(playerData, profession, level + 1));
new ConfigMessage("profession-level-up").addPlaceholders("level", "" + (level + 1), "profession", profession.getName()).send(playerData.getPlayer()); new ConfigMessage("profession-level-up").addPlaceholders("level", "" + (level + 1), "profession", profession.getName()).send(playerData.getPlayer());

View File

@ -41,7 +41,7 @@ import net.Indyuce.mmocore.manager.ClassManager;
import net.mmogroup.mmolib.version.VersionMaterial; import net.mmogroup.mmolib.version.VersionMaterial;
public class PlayerClass { public class PlayerClass {
private final String name, id, fileName; private final String name, id, fileName, expCurve;
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>(); private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
private final ItemStack icon; private final ItemStack icon;
private final Map<ClassOption, Boolean> options = new HashMap<>(); private final Map<ClassOption, Boolean> options = new HashMap<>();
@ -94,6 +94,7 @@ public class PlayerClass {
manaDisplay = new ManaDisplayOptions(config.getConfigurationSection("mana")); manaDisplay = new ManaDisplayOptions(config.getConfigurationSection("mana"));
maxLevel = config.getInt("max-level"); maxLevel = config.getInt("max-level");
displayOrder = config.getInt("display-order"); displayOrder = config.getInt("display-order");
expCurve = config.getString("exp-curve", "levels");
if (config.contains("attributes")) if (config.contains("attributes"))
for (String key : config.getConfigurationSection("attributes").getKeys(false)) for (String key : config.getConfigurationSection("attributes").getKeys(false))
@ -175,6 +176,7 @@ public class PlayerClass {
manaDisplay = new ManaDisplayOptions(ChatColor.BLUE, "Mana", AltChar.listSquare.charAt(0)); manaDisplay = new ManaDisplayOptions(ChatColor.BLUE, "Mana", AltChar.listSquare.charAt(0));
maxLevel = 0; maxLevel = 0;
displayOrder = 0; displayOrder = 0;
expCurve = "";
this.icon = new ItemStack(material); this.icon = new ItemStack(material);
setOption(ClassOption.DISPLAY, false); setOption(ClassOption.DISPLAY, false);
@ -215,6 +217,10 @@ public class PlayerClass {
return displayOrder; return displayOrder;
} }
public String getEXPCurve() {
return expCurve;
}
public String getFileName() { public String getFileName() {
return fileName; return fileName;
} }

View File

@ -34,12 +34,12 @@ public class InfoCommandMap extends CommandEnd {
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------"); sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
sender.sendMessage(ChatColor.YELLOW + "Class: " + ChatColor.GOLD + playerData.getProfess().getName()); sender.sendMessage(ChatColor.YELLOW + "Class: " + ChatColor.GOLD + playerData.getProfess().getName());
sender.sendMessage(ChatColor.YELLOW + "Level: " + ChatColor.GOLD + playerData.getLevel()); sender.sendMessage(ChatColor.YELLOW + "Level: " + ChatColor.GOLD + playerData.getLevel());
sender.sendMessage(ChatColor.YELLOW + "Experience: " + ChatColor.GOLD + playerData.getExperience() + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.configManager.getNeededExperience(playerData.getLevel() + 1)); sender.sendMessage(ChatColor.YELLOW + "Experience: " + ChatColor.GOLD + playerData.getExperience() + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.configManager.getNeededExperience(playerData.getLevel() + 1, playerData.getProfess()));
sender.sendMessage(ChatColor.YELLOW + "Class Points: " + ChatColor.GOLD + playerData.getClassPoints()); sender.sendMessage(ChatColor.YELLOW + "Class Points: " + ChatColor.GOLD + playerData.getClassPoints());
sender.sendMessage(ChatColor.YELLOW + "Quests: " + ChatColor.GOLD + playerData.getQuestData().getFinishedQuests().size() + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.questManager.getAll().size()); sender.sendMessage(ChatColor.YELLOW + "Quests: " + ChatColor.GOLD + playerData.getQuestData().getFinishedQuests().size() + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.questManager.getAll().size());
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------"); sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
for (Profession profession : MMOCore.plugin.professionManager.getAll()) for (Profession profession : MMOCore.plugin.professionManager.getAll())
sender.sendMessage(ChatColor.YELLOW + profession.getName() + ": Lvl " + ChatColor.GOLD + playerData.getCollectionSkills().getLevel(profession) + ChatColor.YELLOW + " - " + ChatColor.GOLD + playerData.getCollectionSkills().getExperience(profession) + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.configManager.getNeededExperience(playerData.getCollectionSkills().getLevel(profession) + 1)); sender.sendMessage(ChatColor.YELLOW + profession.getName() + ": Lvl " + ChatColor.GOLD + playerData.getCollectionSkills().getLevel(profession) + ChatColor.YELLOW + " - " + ChatColor.GOLD + playerData.getCollectionSkills().getExperience(profession) + ChatColor.YELLOW + " / " + ChatColor.GOLD + MMOCore.plugin.configManager.getNeededExperience(playerData.getCollectionSkills().getLevel(profession) + 1, profession));
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------"); sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }

View File

@ -38,7 +38,7 @@ public class RPGPlaceholders extends PlaceholderExpansion /** implements Relatio
else if (identifier.equals("level_percent")) { else if (identifier.equals("level_percent")) {
PlayerData playerData = PlayerData.get(player); PlayerData playerData = PlayerData.get(player);
double current = playerData.getExperience(), next = MMOCore.plugin.configManager.getNeededExperience(playerData.getLevel() + 1); double current = playerData.getExperience(), next = MMOCore.plugin.configManager.getNeededExperience(playerData.getLevel() + 1, playerData.getProfess());
return MMOCore.plugin.configManager.decimal.format(current / next * 100); return MMOCore.plugin.configManager.decimal.format(current / next * 100);
} }
@ -57,7 +57,7 @@ public class RPGPlaceholders extends PlaceholderExpansion /** implements Relatio
else if (identifier.startsWith("profession_percent_")) { else if (identifier.startsWith("profession_percent_")) {
Professions professions = PlayerData.get(player).getCollectionSkills(); Professions professions = PlayerData.get(player).getCollectionSkills();
String profession = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase(); String profession = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase();
double current = professions.getExperience(profession), next = MMOCore.plugin.configManager.getNeededExperience(professions.getLevel(profession) + 1); double current = professions.getExperience(profession), next = MMOCore.plugin.configManager.getNeededExperience(professions.getLevel(profession) + 1, profession);
return MMOCore.plugin.configManager.decimal.format(current / next * 100); return MMOCore.plugin.configManager.decimal.format(current / next * 100);
} }
@ -71,7 +71,7 @@ public class RPGPlaceholders extends PlaceholderExpansion /** implements Relatio
return "" + PlayerData.get(player).getExperience(); return "" + PlayerData.get(player).getExperience();
else if (identifier.equals("next_level")) else if (identifier.equals("next_level"))
return "" + MMOCore.plugin.configManager.getNeededExperience(PlayerData.get(player).getLevel() + 1); return "" + MMOCore.plugin.configManager.getNeededExperience(PlayerData.get(player).getLevel() + 1, PlayerData.get(player).getProfess());
else if (identifier.equals("class_points")) else if (identifier.equals("class_points"))
return "" + PlayerData.get(player).getClassPoints(); return "" + PlayerData.get(player).getClassPoints();

View File

@ -47,7 +47,7 @@ public class ClassConfirmation extends EditableInventory {
SavedClassInformation info = inv.getPlayerData().getClassInfo(profess); SavedClassInformation info = inv.getPlayerData().getClassInfo(profess);
Placeholders holders = new Placeholders(); Placeholders holders = new Placeholders();
int nextLevelExp = MMOCore.plugin.configManager.getNeededExperience(info.getLevel() + 1); int nextLevelExp = MMOCore.plugin.configManager.getNeededExperience(info.getLevel() + 1, profess);
double ratio = (double) info.getExperience() / (double) nextLevelExp; double ratio = (double) info.getExperience() / (double) nextLevelExp;
String bar = "" + ChatColor.BOLD; String bar = "" + ChatColor.BOLD;

View File

@ -79,7 +79,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) / MMOCore.plugin.configManager.getNeededExperience(inv.getPlayerData().getCollectionSkills().getLevel(profession) + 1); double ratio = (double) inv.getPlayerData().getCollectionSkills().getExperience(profession) / MMOCore.plugin.configManager.getNeededExperience(inv.getPlayerData().getCollectionSkills().getLevel(profession) + 1, profession);
String bar = "" + ChatColor.BOLD; String bar = "" + ChatColor.BOLD;
int chars = (int) (ratio * 20); int chars = (int) (ratio * 20);
@ -277,7 +277,7 @@ public class PlayerStats extends EditableInventory {
PlayerData data = inv.getPlayerData(); PlayerData data = inv.getPlayerData();
Placeholders holders = new Placeholders(); Placeholders holders = new Placeholders();
int nextLevelExp = MMOCore.plugin.configManager.getNeededExperience(data.getLevel() + 1); int nextLevelExp = MMOCore.plugin.configManager.getNeededExperience(data.getLevel() + 1, data.getProfess());
double ratio = (double) data.getExperience() / (double) nextLevelExp; double ratio = (double) data.getExperience() / (double) nextLevelExp;
String bar = "" + ChatColor.BOLD; String bar = "" + ChatColor.BOLD;

View File

@ -8,7 +8,9 @@ import java.nio.file.Files;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -18,7 +20,9 @@ import org.bukkit.util.Consumer;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.util.input.AnvilGUI; import net.Indyuce.mmocore.api.util.input.AnvilGUI;
import net.Indyuce.mmocore.api.util.input.ChatInput; import net.Indyuce.mmocore.api.util.input.ChatInput;
import net.Indyuce.mmocore.api.util.input.PlayerInput; import net.Indyuce.mmocore.api.util.input.PlayerInput;
@ -35,7 +39,7 @@ public class ConfigManager {
public final DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols(); public final DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols();
public final DecimalFormat decimal = new DecimalFormat("0.#", formatSymbols), decimals = new DecimalFormat("0.##", formatSymbols); public final DecimalFormat decimal = new DecimalFormat("0.#", formatSymbols), decimals = new DecimalFormat("0.##", formatSymbols);
private List<Integer> neededExp = new ArrayList<>(); private Map<String, List<Integer>> neededExp = new HashMap<String, List<Integer>>();
private FileConfiguration messages; private FileConfiguration messages;
private boolean chatInput; private boolean chatInput;
@ -79,10 +83,14 @@ public class ConfigManager {
loadDefaultFile("classes", "warrior.yml"); loadDefaultFile("classes", "warrior.yml");
} }
if (!new File(MMOCore.plugin.getDataFolder() + "/expcurves").exists()) {
loadDefaultFile("expcurves", "levels.txt");
loadDefaultFile("expcurves", "mining.txt");
}
loadDefaultFile("attributes.yml"); loadDefaultFile("attributes.yml");
loadDefaultFile("items.yml"); loadDefaultFile("items.yml");
loadDefaultFile("messages.yml"); loadDefaultFile("messages.yml");
loadDefaultFile("levels.txt");
loadDefaultFile("stats.yml"); loadDefaultFile("stats.yml");
loadDefaultFile("waypoints.yml"); loadDefaultFile("waypoints.yml");
loadDefaultFile("restrictions.yml"); loadDefaultFile("restrictions.yml");
@ -111,20 +119,24 @@ public class ConfigManager {
staminaEmpty = getColorOrDefault("stamina-empty", ChatColor.WHITE); staminaEmpty = getColorOrDefault("stamina-empty", ChatColor.WHITE);
neededExp.clear(); neededExp.clear();
for(File txt : new File(MMOCore.plugin.getDataFolder() + "/expcurves").listFiles()) {
int line = 0; int line = 0;
try { try {
line++; line++;
File txt = new File(MMOCore.plugin.getDataFolder(), "levels.txt"); //File txt = new File(MMOCore.plugin.getDataFolder(), "levels.txt");
BufferedReader reader = new BufferedReader(new FileReader(txt)); BufferedReader reader = new BufferedReader(new FileReader(txt));
String readLine; String readLine;
List<Integer> levels = new ArrayList<>();
while ((readLine = reader.readLine()) != null) while ((readLine = reader.readLine()) != null)
neededExp.add(Integer.valueOf(readLine)); levels.add(Integer.valueOf(readLine));
neededExp.put(txt.getName().toLowerCase().replace(".txt", ""), levels);
reader.close(); reader.close();
} catch (IOException | IllegalArgumentException e) { } catch (IOException | IllegalArgumentException e) {
MMOCore.plugin.getLogger().log(Level.SEVERE, "Could not read line " + line + " from levels.txt"); MMOCore.plugin.getLogger().log(Level.SEVERE, "Could not read line " + line + " from " + txt.getName());
e.printStackTrace(); e.printStackTrace();
} }
} }
}
private ChatColor getColorOrDefault(String key, ChatColor defaultColor) { private ChatColor getColorOrDefault(String key, ChatColor defaultColor) {
try { try {
@ -166,8 +178,22 @@ public class ConfigManager {
} }
} }
public int getNeededExperience(int level) { public int getNeededExperience(int level, PlayerClass clas) {
return neededExp.get(level - 1 >= neededExp.size() ? neededExp.size() - 1 : level - 1); if(clas == null) return getNeededExperience(level, MMOCore.plugin.classManager.getDefaultClass().getEXPCurve());
return getNeededExperience(level, clas.getEXPCurve());
}
public int getNeededExperience(int level, Profession prof) {
return getNeededExperience(level, prof.getEXPCurve());
}
public int getNeededExperience(int level, String curve) {
List<Integer> expCurve = neededExp.get(curve);
if(expCurve == null) {
MMOCore.log(Level.SEVERE, "Couldn't load EXPCurve: '" + curve + "'. Does it exist?");
return 1;
}
return expCurve.get(level - 1 >= expCurve.size() ? expCurve.size() - 1 : level - 1);
} }
public List<String> getMessage(String key) { public List<String> getMessage(String key) {

View File

@ -32,6 +32,9 @@ display:
- '&7 Mana Regen: &90.2 &7(+&90.04&7)' - '&7 Mana Regen: &90.2 &7(+&90.04&7)'
item: BLAZE_POWDER:1 # Supports custom model data/texture by durability item: BLAZE_POWDER:1 # Supports custom model data/texture by durability
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -9,6 +9,9 @@ options:
off-combat-health-regen: false off-combat-health-regen: false
off-combat-mana-regen: false off-combat-mana-regen: false
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
mana: mana:
char: char:
color: BLUE color: BLUE

View File

@ -26,6 +26,9 @@ display:
- '&7 Mana Regen: &90.2 &7(+&90.04&7)' - '&7 Mana Regen: &90.2 &7(+&90.04&7)'
item: BLAZE_POWDER item: BLAZE_POWDER
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -25,6 +25,9 @@ display:
- '&7 Mana Regen: &90.166 &7(+&90&7)' - '&7 Mana Regen: &90.166 &7(+&90&7)'
item: BOW item: BOW
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -27,6 +27,9 @@ display:
- '&7 Mana Regen: &90.166 &7(+&90&7)' - '&7 Mana Regen: &90.166 &7(+&90&7)'
item: ENCHANTED_GOLDEN_APPLE:0 # Supports custom model data/texture by durability item: ENCHANTED_GOLDEN_APPLE:0 # Supports custom model data/texture by durability
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -25,6 +25,9 @@ display:
- '&7 Mana Regen: &90.166 &7(+&90&7)' - '&7 Mana Regen: &90.166 &7(+&90&7)'
item: LEATHER_BOOTS item: LEATHER_BOOTS
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -30,6 +30,9 @@ display:
- '&7 Rage Degeneration: &9-0.5&7/s' - '&7 Rage Degeneration: &9-0.5&7/s'
item: IRON_SWORD:0 # Supports custom model data/texture by durability item: IRON_SWORD:0 # Supports custom model data/texture by durability
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: levels
# Players cannot go further than Lvl 100 # Players cannot go further than Lvl 100
max-level: 100 max-level: 100

View File

@ -0,0 +1,25 @@
100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
1900
2000
2100
2200
2300
2400
2500

View File

@ -8,6 +8,9 @@ experience:
base: 20 base: 20
per-level: 3 per-level: 3
# Must match an existing exp curve filename from the 'expcurves' folder
exp-curve: mining
# This part of the config is ONLY for custom mining. # This part of the config is ONLY for custom mining.
# Custom Mining must be setup in config.yml and it # Custom Mining must be setup in config.yml and it
# will render any block not referenced in here as unminable. # will render any block not referenced in here as unminable.