Merge branch 'master' into Skills-update

# Conflicts:
#	MMOCore-API/pom.xml
#	MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
#	MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java
#	MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLDataProvider.java
#	MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java
#	MMOCore-API/src/main/java/net/Indyuce/mmocore/player/DefaultPlayerData.java
#	MMOCore-Dist/pom.xml
#	README.md
#	pom.xml
This commit is contained in:
Ka0rX 2023-03-31 09:18:33 +01:00
commit af2c68054e
49 changed files with 685 additions and 280 deletions

View File

@ -293,6 +293,8 @@ public class MMOCore extends JavaPlugin {
for (PlayerData data : PlayerData.getAll())
if (data.isFullyLoaded()) {
data.close();
//Saves player health before saveData as the player will be considered offline into it if it is async.
data.setHealth(data.getPlayer().getHealth());
dataProvider.getDataManager().saveData(data, true);
}
@ -341,7 +343,6 @@ public class MMOCore extends JavaPlugin {
statManager.initialize(clearBefore);
professionManager.initialize(clearBefore);
InventoryManager.load();
skillTreeManager.initialize(clearBefore);
classManager.initialize(clearBefore);
questManager.initialize(clearBefore);
@ -351,6 +352,8 @@ public class MMOCore extends JavaPlugin {
requestManager.initialize(clearBefore);
soundManager.initialize(clearBefore);
configItems.initialize(clearBefore);
//Needs to be loaded after the class manager.
InventoryManager.load();
if (getConfig().isConfigurationSection("action-bar"))
actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));

View File

@ -12,15 +12,12 @@ import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.event.unlocking.ItemLockedEvent;
import net.Indyuce.mmocore.api.event.unlocking.ItemUnlockedEvent;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.player.profess.Subclass;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.profess.skillbinding.BoundSkillInfo;
import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
import net.Indyuce.mmocore.api.quest.PlayerQuests;
@ -36,10 +33,9 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.party.provided.Party;
import net.Indyuce.mmocore.player.ClassDataContainer;
import net.Indyuce.mmocore.player.CombatHandler;
import net.Indyuce.mmocore.player.Unlockable;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
@ -67,6 +63,7 @@ import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer, ClassDataContainer {
/**
@ -86,6 +83,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private int skillTreeReallocationPoints, skillReallocationPoints;
private double experience;
private double mana, stamina, stellium;
/**
* Health is stored in playerData because when saving the playerData we can't access the player health anymore as the payer is Offline.
*/
private double health;
private Guild guild;
private SkillCastingHandler skillCasting;
private final PlayerQuests questData;
@ -141,11 +142,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
this.mmoData = mmoData;
questData = new PlayerQuests(this);
playerStats = new PlayerStats(this);
}
/**
* Update all references after /mmocore reload so there can be garbage
* collection with old plugin objects like class or skill instances.
@ -187,11 +185,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
skillTree.setupNodeStates(this);
// Stat triggers setup
if (!areStatsLoaded()) {
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().claimStatTriggers(this, node);
}
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().claimStatTriggers(this, node);
}
public int getPointSpent(SkillTree skillTree) {
@ -244,15 +242,18 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return nodeLevelsString.entrySet();
}
public boolean areStatsLoaded() {
// Used to see if the triggers need to be applied
for (StatInstance instance : mmoData.getStatMap().getInstances())
for (StatModifier modifier : instance.getModifiers())
public void resetTriggerStats() {
for (StatInstance instance : mmoData.getStatMap().getInstances()) {
Iterator<StatModifier> iter = instance.getModifiers().iterator();
while (iter.hasNext()) {
StatModifier modifier = iter.next();
if (modifier.getKey().startsWith(StatTrigger.TRIGGER_PREFIX))
return true;
return false;
iter.remove();
}
}
}
public Map<SkillTreeNode, Integer> getNodeLevels() {
return new HashMap<>(nodeLevels);
}
@ -435,13 +436,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
@Override
public void close() {
// Remove from party if it is MMO Party Module
if (MMOCore.plugin.partyModule instanceof MMOCorePartyModule) {
AbstractParty party = getParty();
if (party != null && party instanceof Party)
((Party) party).removeMember(this);
}
// Close combat handler
combat.close();
@ -803,9 +797,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
final double r = Math.sin((double) t / warpTime * Math.PI);
for (double j = 0; j < Math.PI * 2; j += Math.PI / 4)
getPlayer().getLocation().getWorld().spawnParticle(Particle.REDSTONE, getPlayer().getLocation().add(
Math.cos((double) 5 * t / warpTime + j) * r,
(double) 2 * t / warpTime,
Math.sin((double) 5 * t / warpTime + j) * r),
Math.cos((double) 5 * t / warpTime + j) * r,
(double) 2 * t / warpTime,
Math.sin((double) 5 * t / warpTime + j) * r),
1, new Particle.DustOptions(Color.PURPLE, 1.25f));
}
}.runTaskTimer(MMOCore.plugin, 0, 1);
@ -992,13 +986,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
}
@Override
public double getHealth() {
return getPlayer().getHealth();
public double getMana() {
return mana;
}
@Override
public double getMana() {
return mana;
public double getHealth() {
return health;
}
@Override
@ -1023,6 +1017,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
mana = Math.max(0, Math.min(amount, getStats().getStat("MAX_MANA")));
}
public void setHealth(double amount) {
this.health = amount;
}
public void setStamina(double amount) {
stamina = Math.max(0, Math.min(amount, getStats().getStat("MAX_STAMINA")));
}

View File

@ -6,17 +6,14 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.player.ClassDataContainer;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Set;
public class SavedClassInformation {
private final int level, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints;
@ -39,10 +36,10 @@ public class SavedClassInformation {
attributeReallocationPoints = config.getInt("attribute-realloc-points");
skillReallocationPoints = config.getInt("skill-reallocation-points");
skillTreeReallocationPoints = config.getInt("skill-tree-reallocation-points");
health = config.getInt("health", 20);
mana = config.getInt("mana", 0);
stamina = config.getInt("stamina", 0);
stellium = config.getInt("stellium", 0);
health = config.getDouble("health", 20);
mana = config.getDouble("mana", 0);
stamina = config.getDouble("stamina", 0);
stellium = config.getDouble("stellium", 0);
if (config.contains("attribute"))
config.getConfigurationSection("attribute").getKeys(false)
.forEach(key -> attributeLevels.put(key, config.getInt("attribute." + key)));
@ -80,6 +77,7 @@ public class SavedClassInformation {
mana = json.has("mana") ? json.get("mana").getAsDouble() : 0;
stamina = json.has("stamina") ? json.get("stamina").getAsDouble() : 0;
stellium = json.has("stellium") ? json.get("stellium").getAsDouble() : 0;
if (json.has("attribute"))
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
attributeLevels.put(entry.getKey(), entry.getValue().getAsInt());
@ -118,6 +116,7 @@ public class SavedClassInformation {
this.mana = data.getMana();
this.stellium = data.getStellium();
this.stamina = data.getStamina();
data.mapAttributeLevels().forEach((key, val) -> this.attributeLevels.put(key, val));
data.mapSkillLevels().forEach((key, val) -> skillLevels.put(key, val));
data.mapSkillTreePoints().forEach((key, val) -> skillTreePoints.put(key, val));
@ -147,6 +146,22 @@ public class SavedClassInformation {
return attributeReallocationPoints;
}
public double getHealth() {
return health;
}
public double getMana() {
return mana;
}
public double getStellium() {
return stellium;
}
public double getStamina() {
return stamina;
}
public Set<String> getSkillKeys() {
return skillLevels.keySet();
}
@ -195,26 +210,6 @@ public class SavedClassInformation {
return skillTreePoints.get(skillTreeId);
}
public double getHealth() {
return health;
}
public double getMana() {
return mana;
}
public double getStellium() {
return stellium;
}
public double getStamina() {
return stamina;
}
public Set<String> getUnlockedItems() {
return unlockedItems;
}
public Set<String> getAttributeKeys() {
return attributeLevels.keySet();
}
@ -311,11 +306,12 @@ public class SavedClassInformation {
player.setClass(profess);
player.unloadClassInfo(profess);
//This needs to be done at the end to make sure the MAX_HEALTH,MAX_MANA,MAX_STELLIUM... stats are loaded.
player.getPlayer().setHealth(Math.min(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
//These should be loaded after to make sure that the MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
player.setMana(mana);
player.setStellium(stellium);
player.setStamina(stamina);
player.getPlayer().setHealth(Math.min(health,player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
// Updates level on exp bar
player.refreshVanillaExp();
}

View File

@ -31,6 +31,10 @@ public class PartyCommand extends RegisteredCommand {
sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true;
}
if(!(MMOCore.plugin.partyModule instanceof MMOCorePartyModule)){
sender.sendMessage(ChatColor.RED+"You can't use MMOCore party system as you delegated the party system to another plugin.");
return true;
}
PlayerData data = PlayerData.get((OfflinePlayer) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "party");

View File

@ -101,15 +101,12 @@ public class PlayerProfessions {
for (Entry<String, JsonElement> entry : obj.getAsJsonObject("timesClaimed").entrySet())
playerData.getItemClaims().put("profession." + entry.getKey(), entry.getValue().getAsInt());
if (!playerData.areStatsLoaded()) {
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
if (profession.hasExperienceTable())
profession.getExperienceTable().claimStatTriggers(playerData, profession);
}
if (playerData.getProfess().hasExperienceTable())
playerData.getProfess().getExperienceTable().claimStatTriggers(playerData, playerData.getProfess());
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
if (profession.hasExperienceTable())
profession.getExperienceTable().claimStatTriggers(playerData, profession);
}
if (playerData.getProfess().hasExperienceTable())
playerData.getProfess().getExperienceTable().claimStatTriggers(playerData, playerData.getProfess());
}
@ -240,11 +237,11 @@ public class PlayerProfessions {
}
StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
int chars = (int) ((double) exp / needed * 20);
int chars = (int) (exp / needed * 20);
for (int j = 0; j < 20; j++)
bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
if (playerData.isOnline())
MMOCore.plugin.configManager.getSimpleMessage("exp-notification", "profession", profession.getName(), "progress", bar.toString(), "ratio",
MythicLib.plugin.getMMOConfig().decimal.format((double) exp / needed * 100)).send(playerData.getPlayer());
MythicLib.plugin.getMMOConfig().decimal.format(exp / needed * 100)).send(playerData.getPlayer());
}
}

View File

@ -1,12 +1,12 @@
package net.Indyuce.mmocore.gui;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
@ -21,21 +21,14 @@ import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class ClassConfirmation extends EditableInventory {
/**
* This enables to configure the name of the
* class confirmation GUI (for custom GUI textures).
*/
private final Map<String, String> specificNames = new HashMap<>();
private final PlayerClass playerClass;
public ClassConfirmation() {
super("class-confirm");
public ClassConfirmation(PlayerClass playerClass) {
super("class-confirm-"+ UtilityMethods.ymlName(playerClass.getId()));
this.playerClass=playerClass;
}
@Override
@ -43,21 +36,13 @@ public class ClassConfirmation extends EditableInventory {
return function.equalsIgnoreCase("yes") ? new YesItem(config) : new SimplePlaceholderItem(config);
}
public GeneratedInventory newInventory(PlayerData data, PlayerClass profess, PluginInventory last) {
return new ClassConfirmationInventory(data, this, profess, last);
public GeneratedInventory newInventory(PlayerData data, PluginInventory last) {
return new ClassConfirmationInventory(data, this, playerClass, last);
}
@Override
public void reload(FileConfiguration config) {
super.reload(config);
specificNames.clear();
if (config.contains("class-specific-name")) {
final ConfigurationSection section = config.getConfigurationSection("class-specific-name");
for (String key : section.getKeys(false))
specificNames.put(key, section.getString(key));
}
}
public class UnlockedItem extends InventoryItem<ClassConfirmationInventory> {
@ -154,9 +139,7 @@ public class ClassConfirmation extends EditableInventory {
@Override
public String calculateName() {
final String professKey = MMOCoreUtils.ymlName(profess.getId());
final @Nullable String found = specificNames.get(professKey);
return found == null ? getName().replace("{class}", profess.getName()) : found;
return getName().replace("{class}", profess.getName());
}
}
}

View File

@ -1,18 +1,21 @@
package net.Indyuce.mmocore.gui;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.manager.InventoryManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
@ -24,6 +27,7 @@ import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class ClassSelect extends EditableInventory {
@ -33,7 +37,7 @@ public class ClassSelect extends EditableInventory {
@Override
public InventoryItem load(String function, ConfigurationSection config) {
return function.equals("class") ? new ClassItem(config) : new SimplePlaceholderItem(config);
return function.startsWith("class") ? new ClassItem(config) : new SimplePlaceholderItem(config);
}
public GeneratedInventory newInventory(PlayerData data) {
@ -43,10 +47,13 @@ public class ClassSelect extends EditableInventory {
public class ClassItem extends SimplePlaceholderItem<ProfessSelectionInventory> {
private final String name;
private final List<String> lore;
private final PlayerClass playerClass;
public ClassItem(ConfigurationSection config) {
super(Material.BARRIER, config);
Validate.isTrue(config.getString("function").length()>6,"Couldn't find the class associated to: "+config.getString("function"));
String classId = UtilityMethods.enumName(config.getString("function").substring(6));
this.playerClass = Objects.requireNonNull(MMOCore.plugin.classManager.get(classId),classId+" does not correspond to any classId.");
this.name = config.getString("name");
this.lore = config.getStringList("lore");
}
@ -60,29 +67,28 @@ public class ClassSelect extends EditableInventory {
if (n >= inv.classes.size())
return null;
PlayerClass profess = inv.classes.get(n);
ItemStack item = profess.getIcon();
ItemStack item = playerClass.getIcon();
ItemMeta meta = item.getItemMeta();
if (hideFlags())
meta.addItemFlags(ItemFlag.values());
meta.setDisplayName(MythicLib.plugin.parseColors(name).replace("{name}", profess.getName()));
meta.setDisplayName(MythicLib.plugin.parseColors(name).replace("{name}", playerClass.getName()));
List<String> lore = new ArrayList<>(this.lore);
int index = lore.indexOf("{lore}");
if (index >= 0) {
lore.remove(index);
for (int j = 0; j < profess.getDescription().size(); j++)
lore.add(index + j, profess.getDescription().get(j));
for (int j = 0; j < playerClass.getDescription().size(); j++)
lore.add(index + j, playerClass.getDescription().get(j));
}
index = lore.indexOf("{attribute-lore}");
if (index >= 0) {
lore.remove(index);
for (int j = 0; j < profess.getAttributeDescription().size(); j++)
lore.add(index + j, profess.getAttributeDescription().get(j));
for (int j = 0; j < playerClass.getAttributeDescription().size(); j++)
lore.add(index + j, playerClass.getAttributeDescription().get(j));
}
meta.getPersistentDataContainer().set(new NamespacedKey(MMOCore.plugin, "class_id"), PersistentDataType.STRING, profess.getId());
meta.getPersistentDataContainer().set(new NamespacedKey(MMOCore.plugin, "class_id"), PersistentDataType.STRING, playerClass.getId());
meta.setLore(lore);
item.setItemMeta(meta);
return item;
@ -104,10 +110,8 @@ public class ClassSelect extends EditableInventory {
@Override
public void whenClicked(InventoryClickContext context, InventoryItem item) {
if (item.getFunction().equals("class")) {
String classId = context.getClickedItem().getItemMeta().getPersistentDataContainer().get(new NamespacedKey(MMOCore.plugin, "class_id"), PersistentDataType.STRING);
if (classId.equals(""))
return;
if (item instanceof ClassItem) {
PlayerClass profess = ((ClassItem) item).playerClass;
if (playerData.getClassPoints() < 1) {
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
@ -115,7 +119,6 @@ public class ClassSelect extends EditableInventory {
return;
}
final PlayerClass profess = MMOCore.plugin.classManager.get(classId);
if (profess.hasOption(ClassOption.NEEDS_PERMISSION) && !player.hasPermission("mmocore.class." + profess.getId().toLowerCase())) {
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
new ConfigMessage("no-permission-for-class").send(player);
@ -129,7 +132,7 @@ public class ClassSelect extends EditableInventory {
}
final PlayerClass playerClass = findDeepestSubclass(playerData, profess);
InventoryManager.CLASS_CONFIRM.newInventory(playerData, playerClass, this).open();
InventoryManager.CLASS_CONFIRM.get(MMOCoreUtils.ymlName(playerClass.getId())).newInventory(playerData, this).open();
}
}
}

View File

@ -130,7 +130,7 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
}
public ItemStack display(T inv) {
return display(inv, 0);
return display(inv, modelData);
}
public ItemStack display(T inv, int n) {
@ -138,7 +138,7 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
}
public ItemStack display(T inv, int n, Material specificMaterial) {
return display(inv, n, specificMaterial, 0);
return display(inv, n, specificMaterial, modelData);
}
public ItemStack display(T inv, int n, Material specificMaterial, int modelData) {

View File

@ -130,6 +130,7 @@ public class ConfigManager {
fishingDropsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.fishing-drops");
maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
partyMaxExpSplitRange = MMOCore.plugin.getConfig().getDouble("party.max-exp-split-range");
splitMainExp = MMOCore.plugin.getConfig().getBoolean("party.main-exp-split");
splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar");

View File

@ -1,10 +1,11 @@
package net.Indyuce.mmocore.manager;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.logging.Level;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.gui.social.friend.EditableFriendList;
import net.Indyuce.mmocore.gui.*;
import net.Indyuce.mmocore.gui.social.friend.EditableFriendRemoval;
@ -20,7 +21,7 @@ public class InventoryManager {
public static final SkillList SKILL_LIST = new SkillList();
public static final ClassSelect CLASS_SELECT = new ClassSelect();
public static final SubclassSelect SUBCLASS_SELECT = new SubclassSelect();
public static final ClassConfirmation CLASS_CONFIRM = new ClassConfirmation();
public static final Map<String, ClassConfirmation> CLASS_CONFIRM = new HashMap<>();
public static final SubclassConfirmation SUBCLASS_CONFIRM = new SubclassConfirmation();
public static final WaypointViewer WAYPOINTS = new WaypointViewer();
public static final EditableFriendList FRIEND_LIST = new EditableFriendList();
@ -32,14 +33,21 @@ public class InventoryManager {
public static final QuestViewer QUEST_LIST = new QuestViewer();
public static final AttributeView ATTRIBUTE_VIEW = new AttributeView();
public static final SkillTreeViewer TREE_VIEW = new SkillTreeViewer();
public static final List<EditableInventory> list = Arrays.asList(PLAYER_STATS, ATTRIBUTE_VIEW, TREE_VIEW,SKILL_LIST, CLASS_SELECT, SUBCLASS_SELECT, SUBCLASS_CONFIRM, QUEST_LIST, WAYPOINTS, CLASS_CONFIRM, FRIEND_LIST, FRIEND_REMOVAL, PARTY_VIEW, PARTY_CREATION, GUILD_VIEW, GUILD_CREATION);
public static final List<EditableInventory> list = new ArrayList(Arrays.asList(PLAYER_STATS, ATTRIBUTE_VIEW, TREE_VIEW, SKILL_LIST, CLASS_SELECT, SUBCLASS_SELECT, SUBCLASS_CONFIRM, QUEST_LIST, WAYPOINTS, FRIEND_LIST, FRIEND_REMOVAL, PARTY_VIEW, PARTY_CREATION, GUILD_VIEW, GUILD_CREATION));
public static void load() {
for (PlayerClass playerClass : MMOCore.plugin.classManager.getAll()) {
ClassConfirmation GUI = new ClassConfirmation(playerClass);
CLASS_CONFIRM.put(MMOCoreUtils.ymlName(playerClass.getId()), GUI);
list.add(GUI);
}
list.forEach(inv -> {
MMOCore.plugin.configManager.loadDefaultFile("gui", inv.getId() + ".yml");
String folder="gui"+(inv instanceof ClassConfirmation?"/class-confirm":"");
MMOCore.plugin.configManager.loadDefaultFile(folder, inv.getId() + ".yml");
try {
inv.reload(new ConfigFile("/gui", inv.getId()).getConfig());
} catch (IllegalArgumentException exception) {
inv.reload(new ConfigFile("/"+folder, inv.getId()).getConfig());
} catch (Exception exception) {
MMOCore.log(Level.WARNING, "Could not load inventory '" + inv.getId() + "': " + exception.getMessage());
}
});

View File

@ -13,6 +13,9 @@ import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.attribute.Attribute;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
@ -33,11 +36,8 @@ public class MMOCoreDataSynchronizer extends DataSynchronizer {
@Override
public void loadData(ResultSet result) throws SQLException {
// Initialize custom resources
data.setMana(result.getFloat("mana"));
data.setStellium(result.getFloat("stellium"));
data.setStamina(result.getFloat("stamina"));
//Reset stats linked to triggers
data.resetTriggerStats();
data.setClassPoints(result.getInt("class_points"));
data.setSkillPoints(result.getInt("skill_points"));
@ -113,6 +113,16 @@ public class MMOCoreDataSynchronizer extends DataSynchronizer {
}
}
//These should be loaded after to make sure that the MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
data.setMana(result.getDouble("mana"));
data.setStamina(result.getDouble("stamina"));
data.setStellium(result.getDouble("stellium"));
double health = result.getDouble("health");
health = health == 0 ? 20 : health;
health = Math.min(health, data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
data.getPlayer().setHealth(health);
UtilityMethods.debug(MMOCore.plugin, "SQL", String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
data.setFullyLoaded();
}

View File

@ -22,9 +22,10 @@ public class MySQLDataProvider extends MMODataSource implements DataProvider {
"skill_tree_points", "LONGTEXT",
"skill_tree_levels", "LONGTEXT",
"unlocked_items","LONGTEXT",
"mana","FLOAT",
"stamina","FLOAT",
"stellium","FLOAT"};
"health", "FLOAT",
"mana", "FLOAT",
"stamina", "FLOAT",
"stellium", "FLOAT"};
public MySQLDataProvider(FileConfiguration config) {
super(MMOCore.plugin);
@ -57,6 +58,10 @@ public class MySQLDataProvider extends MMODataSource implements DataProvider {
"friends LONGTEXT," +
"skills LONGTEXT," +
"bound_skills LONGTEXT," +
"health FLOAT," +
"mana FLOAT," +
"stamina FLOAT," +
"stellium FLOAT," +
"unlocked_items LONGTEXT," +
"class_info LONGTEXT," +
"is_saved TINYINT," +

View File

@ -44,6 +44,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
updater.addData("attribute_realloc_points", data.getAttributeReallocationPoints());
updater.addJSONArray("waypoints", data.getWaypoints());
updater.addData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints());
updater.addData("health",data.getHealth());
updater.addData("mana", data.getMana());
updater.addData("stellium", data.getStellium());
updater.addData("stamina", data.getStamina());

View File

@ -16,7 +16,9 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.stream.Collectors;
@ -31,6 +33,9 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
public void loadData(PlayerData data) {
FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig();
//Reset stats linked to triggers.
data.resetTriggerStats();
data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points", getDefaultData().getSkillReallocationPoints()));
@ -76,10 +81,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
if (config.contains("times-claimed"))
for (
String key : config.getConfigurationSection("times-claimed").
getKeys(false)) {
for (String key : config.getConfigurationSection("times-claimed").getKeys(false)) {
ConfigurationSection section = config.getConfigurationSection("times-claimed." + key);
if (section != null)
for (String key1 : section.getKeys(false)) {
@ -93,8 +95,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
}
data.setUnlockedItems(config.getStringList("unlocked-items").stream().collect(Collectors.toSet()));
for (
SkillTreeNode node : MMOCore.plugin.skillTreeManager.getAllNodes()) {
for (SkillTreeNode node : MMOCore.plugin.skillTreeManager.getAllNodes()) {
data.setNodeLevel(node, config.getInt("skill-tree-level." + node.getFullId(), 0));
}
data.setupSkillTree();
@ -116,16 +117,12 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
//These should be loaded after to make sure that the MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
data.setMana(config.contains("mana") ? config.getDouble("mana") : data.getStats().
getStat("MAX_MANA"));
data.setStamina(config.contains("stamina") ? config.getDouble("stamina") : data.getStats().
getStat("MAX_STAMINA"));
data.setStellium(config.contains("stellium") ? config.getDouble("stellium") : data.getStats().
getStat("MAX_STELLIUM"));
data.setMana(config.contains("mana") ? config.getDouble("mana") : data.getStats().getStat("MAX_MANA"));
data.setStamina(config.contains("stamina") ? config.getDouble("stamina") : data.getStats().getStat("MAX_STAMINA"));
data.setStellium(config.contains("stellium") ? config.getDouble("stellium") : data.getStats().getStat("MAX_STELLIUM"));
double health=config.contains("health") ? config.getDouble("health") : data.getStats().getStat("MAX_HEALTH");
health=Math.min(health,data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
data.getPlayer().setHealth(health);
data.setFullyLoaded();
}
@ -150,6 +147,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
data.mapSkillTreePoints().forEach((key1, value) -> config.set("skill-tree-points." + key1, value));
config.set("skill-tree-reallocation-points", data.getSkillTreeReallocationPoints());
config.set("skill", null);
config.set("health",data.getHealth());
config.set("mana", data.getMana());
config.set("stellium", data.getStellium());
config.set("stamina", data.getStamina());

View File

@ -1,17 +1,30 @@
package net.Indyuce.mmocore.party.compat;
import com.alessiodp.parties.api.events.bukkit.player.BukkitPartiesPlayerPostJoinEvent;
import com.alessiodp.parties.api.events.bukkit.player.BukkitPartiesPlayerPostLeaveEvent;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.event.group.GroupDisbandEvent;
import de.erethon.dungeonsxl.api.event.group.GroupPlayerJoinEvent;
import de.erethon.dungeonsxl.api.event.group.GroupPlayerLeaveEvent;
import de.erethon.dungeonsxl.api.player.PlayerGroup;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.PartyModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class DungeonsXLPartyModule implements PartyModule {
public class DungeonsXLPartyModule implements PartyModule, Listener {
public DungeonsXLPartyModule() {
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
}
@Override
public AbstractParty getParty(PlayerData playerData) {
@ -19,7 +32,43 @@ public class DungeonsXLPartyModule implements PartyModule {
return group == null ? null : new CustomParty(group);
}
class CustomParty implements AbstractParty {
@EventHandler
public void onPlayerJoin(GroupPlayerJoinEvent event) {
//We add 1 because this returns the members of the group excluding the player that just joined.
int membersSize = event.getGroup().getMembers().size() + 1;
applyStatBonuses(PlayerData.get(event.getPlayer().getPlayer()), membersSize);
event.getGroup().getMembers().getOnlinePlayers()
.forEach(p -> applyStatBonuses(PlayerData.get(p), membersSize));
}
@EventHandler
public void onPlayerLeave(GroupPlayerLeaveEvent event) {
int membersSize = event.getGroup().getMembers().size();
clearStatBonuses(PlayerData.get(event.getPlayer().getPlayer()));
event.getGroup().getMembers().getOnlinePlayers()
.forEach(p -> applyStatBonuses(PlayerData.get(p), membersSize));
}
@EventHandler
public void onGroupDisband(GroupDisbandEvent event) {
event.getGroup().getMembers().getOnlinePlayers().forEach(p -> clearStatBonuses(PlayerData.get(p)));
}
/**
* Applies party stat bonuses to a specific player
*/
private void applyStatBonuses(PlayerData player, int membersSize) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.multiply(membersSize - 1).register(player.getMMOPlayerData()));
}
/**
* Clear party stat bonuses from a player
*/
private void clearStatBonuses(PlayerData player) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.unregister(player.getMMOPlayerData()));
}
class CustomParty implements AbstractParty, Listener {
private final PlayerGroup group;
public CustomParty(PlayerGroup group) {
@ -48,5 +97,6 @@ public class DungeonsXLPartyModule implements PartyModule {
public int countMembers() {
return group.getMembers().getUniqueIds().size();
}
}
}

View File

@ -2,17 +2,28 @@ package net.Indyuce.mmocore.party.compat;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.UserManager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.PartyModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class McMMOPartyModule implements PartyModule {
public class McMMOPartyModule implements PartyModule, Listener {
public McMMOPartyModule() {
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
}
@Nullable
@Override
@ -22,11 +33,53 @@ public class McMMOPartyModule implements PartyModule {
return party == null ? null : new CustomParty(party);
}
class CustomParty implements AbstractParty {
@EventHandler
public void onChange(McMMOPartyChangeEvent event) {
if (event.getNewParty() != null) {
Party party = PartyManager.getParty(event.getNewParty());
if (party != null) {
//This is the size of the party before the player joins=> we increment it by 1.
int membersSize = party.getMembers().size();
if(membersSize!=1 || party.getOnlineMembers().get(0)!=event.getPlayer()) {
party.getOnlineMembers()
.forEach(p -> applyStatBonuses(PlayerData.get(p), membersSize+1));
applyStatBonuses(PlayerData.get(event.getPlayer()), membersSize+1);
}
}
}
if (event.getOldParty() != null) {
Party party = PartyManager.getParty(event.getOldParty());
if (party != null) {
//This is the size of the party before the player leaves=> we decrement it by 1.
int membersSize = party.getMembers().size() - 1;
party.getOnlineMembers()
.forEach(p -> applyStatBonuses(PlayerData.get(p), membersSize));
clearStatBonuses(PlayerData.get(event.getPlayer().getPlayer()));
}
}
}
/**
* Applies party stat bonuses to a specific player
*/
private void applyStatBonuses(PlayerData player, int membersSize) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.multiply(membersSize - 1).register(player.getMMOPlayerData()));
}
/**
* Clear party stat bonuses from a player
*/
private void clearStatBonuses(PlayerData player) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.unregister(player.getMMOPlayerData()));
}
class CustomParty implements AbstractParty, Listener {
private final Party party;
public CustomParty(Party party) {
this.party = party;
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
}
@Override

View File

@ -1,20 +1,29 @@
package net.Indyuce.mmocore.party.compat;
import com.alessiodp.parties.api.Parties;
import com.alessiodp.parties.api.events.bukkit.player.BukkitPartiesPlayerPostJoinEvent;
import com.alessiodp.parties.api.events.bukkit.player.BukkitPartiesPlayerPostLeaveEvent;
import com.alessiodp.parties.api.interfaces.PartiesAPI;
import com.alessiodp.parties.api.interfaces.Party;
import com.alessiodp.parties.api.interfaces.PartyPlayer;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.PartyModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class PartiesPartyModule implements PartyModule {
public class PartiesPartyModule implements PartyModule,Listener {
public PartiesPartyModule(){
Bukkit.getPluginManager().registerEvents(this,MMOCore.plugin);
}
@Nullable
@Override
@ -25,7 +34,36 @@ public class PartiesPartyModule implements PartyModule {
return party == null ? null : new CustomParty(party);
}
class CustomParty implements AbstractParty {
@EventHandler
public void onPlayerJoin(BukkitPartiesPlayerPostJoinEvent event){
int membersSize=event.getParty().getMembers().size();
event.getParty().getOnlineMembers()
.forEach(p-> applyStatBonuses(PlayerData.get(p.getPlayerUUID()),membersSize));
}
@EventHandler
public void onPlayerLeave(BukkitPartiesPlayerPostLeaveEvent event){
int membersSize=event.getParty().getMembers().size();
clearStatBonuses(PlayerData.get(event.getPartyPlayer().getPlayerUUID()));
event.getParty().getOnlineMembers()
.forEach(p-> applyStatBonuses(PlayerData.get(p.getPlayerUUID()),membersSize));
}
/**
* Applies party stat bonuses to a specific player
*/
private void applyStatBonuses(PlayerData player,int membersSize) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.multiply(membersSize - 1).register(player.getMMOPlayerData()));
}
/**
* Clear party stat bonuses from a player
*/
private void clearStatBonuses(PlayerData player) {
MMOCore.plugin.partyManager.getBonuses().forEach(buff -> buff.unregister(player.getMMOPlayerData()));
}
class CustomParty implements AbstractParty {
private final Party party;
public CustomParty(Party party) {

View File

@ -1,12 +1,15 @@
package net.Indyuce.mmocore.player;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DefaultPlayerData implements ClassDataContainer {
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints, skillReallocPoints, skillTreeReallocPoints;
@ -21,10 +24,10 @@ public class DefaultPlayerData implements ClassDataContainer {
attrReallocPoints = config.getInt("attribute-realloc-points");
skillReallocPoints = config.getInt("skill-realloc-points", 0);
skillTreeReallocPoints = config.getInt("skill-tree-realloc-points", 0);
health = config.getDouble("health");
mana = config.getDouble("mana");
stellium = config.getDouble("stellium");
stamina = config.getDouble("stamina");
health=config.getDouble("health",20);
mana=config.getDouble("mana",20);
stamina=config.getDouble("stamina",20);
stellium=config.getDouble("stellium",20);
}
public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints, int skillReallocPoints, int skillTreeReallocPoints, double health, double mana, double stamina, double stellium) {
@ -50,6 +53,26 @@ public class DefaultPlayerData implements ClassDataContainer {
return 0;
}
@Override
public double getHealth() {
return health;
}
@Override
public double getMana() {
return mana;
}
@Override
public double getStamina() {
return stamina;
}
@Override
public double getStellium() {
return stellium;
}
@Override
public int getSkillPoints() {
return skillPoints;
@ -79,26 +102,6 @@ public class DefaultPlayerData implements ClassDataContainer {
return skillTreeReallocPoints;
}
@Override
public double getHealth() {
return health;
}
@Override
public double getMana() {
return mana;
}
@Override
public double getStamina() {
return stamina;
}
@Override
public double getStellium() {
return stellium;
}
@Override
public Map<String, Integer> mapSkillLevels() {
return new HashMap<>();
@ -119,11 +122,6 @@ public class DefaultPlayerData implements ClassDataContainer {
return new HashMap<>();
}
@Override
public Set<String> getUnlockedItems() {
return new HashSet<>();
}
@Override
public Map<String, Integer> mapAttributeLevels() {
return new HashMap<>();
@ -142,9 +140,5 @@ public class DefaultPlayerData implements ClassDataContainer {
player.setAttributeReallocationPoints(attrReallocPoints);
player.setSkillTreeReallocationPoints(skillTreeReallocPoints);
player.setSkillReallocationPoints(skillReallocPoints);
player.getPlayer().setHealth(Math.min(health,player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
player.setMana(mana);
player.setStamina(stamina);
player.setStellium(stellium);
}
}

View File

@ -73,6 +73,10 @@ public class PlayerListener implements Listener {
@EventHandler
public void saveDataOnQuit(PlayerQuitEvent event) {
PlayerData playerData = PlayerData.get(event.getPlayer());
/**
* We save player health as it won't be accessible anymore when saving the player data (player will be offline).
*/
playerData.setHealth(event.getPlayer().getHealth());
MMOCore.plugin.dataProvider.getDataManager().unregisterSafe(playerData);
}

View File

@ -131,8 +131,8 @@ party:
# Edit party buffs here. You may
# add as many stats as you want.
buff:
health-regeneration: 3
additional-experience: 5
health-regeneration: 3%
additional-experience: 5%
# Prefix you need to put in the chat
# to talk in the party chat.

View File

@ -1,16 +1,6 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# GUI display name which overrides the default one.
# This can be used to apply custom textures to the GUI
class-specific-name:
mage: "Select Mage"
rogue: "Select Rogue"
marksman: "Select Marksman"
warrior: "Select Warrior"
paladin: "Select Paladin"
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -0,0 +1,38 @@
# GUI display name, used by default
name: 'Confirmation: {class}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 27
items:
yes:
slots: [12]
function: 'yes'
# Displayed when the player had already selected this class
# before (only if class slots are enabled in the config).
unlocked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore:
- ''
- '&7Class Level: &e{level}'
- '&7Progression: &e{exp} / {next_level}'
- '&8[&e{progress}&8] &e{percent}%'
- ''
- '&7Skill Points: &6{skill_points}'
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
# Displayed when the class is being chosen for the first time.
locked:
item: GREEN_TERRACOTTA
name: '&aSelect {class}'
lore: {}
back:
slots: [14]
item: RED_TERRACOTTA
function: back
name: '&aBack'
lore: {}

View File

@ -7,10 +7,51 @@ name: Class Selection
slots: 27
items:
class:
slots: [13,12,14,11,15,10,16]
function: class
name: '&a&lThe {name}'
class-rogue:
slots: [11]
function: class-rogue
name: '&a&lThe Rogue'
hide-flags: true
lore:
- '{lore}'
- ''
- '{attribute-lore}'
class-mage:
slots: [12]
function: class-mage
name: '&a&lThe Mage'
hide-flags: true
lore:
- '{lore}'
- ''
- '{attribute-lore}'
class-marksman:
slots: [13]
function: class-marksman
name: '&a&lThe Marksman'
hide-flags: true
lore:
- '{lore}'
- ''
- '{attribute-lore}'
class-warrior:
slots: [14]
function: class-warrior
name: '&a&lThe Warrior'
hide-flags: true
lore:
- '{lore}'
- ''
- '{attribute-lore}'
class-paladin:
slots: [15]
function: class-paladin
name: '&a&lThe Paladin'
hide-flags: true
lore:
- '{lore}'

View File

@ -12,13 +12,13 @@ lore:
- '&e{cooldown}s Cooldown'
material: EMERALD
mana:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:
@ -28,6 +28,6 @@ cooldown:
min: 1.0
percent:
base: 10.0
per-level: 0.1
per-level: 1.1
max: 20.0
min: 10.0

View File

@ -8,13 +8,13 @@ mana:
base: 8.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:
base: 50.0
per-level: 20.0
cooldown:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0

View File

@ -8,15 +8,15 @@ lore:
material: IRON_SWORD
damage:
base: 9.0
per-level: 0.3
per-level: 1.3
mana:
base: 10.0
per-level: -0.1
max: 5.0
min: 3.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:
@ -26,4 +26,4 @@ cooldown:
min: 5.0
count:
base: 3.0
per-level: 0.2
per-level: 1.2

View File

@ -10,13 +10,13 @@ lore:
material: MAGENTA_DYE
duration:
base: 2.0
per-level: 0.0
per-level: 1.0
mana:
base: 15.0
per-level: 1.5
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -14,8 +14,8 @@ mana:
base: 8.0
per-level: 3.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:

View File

@ -12,8 +12,8 @@ mana:
base: 4.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:
@ -26,7 +26,7 @@ cooldown:
min: 5.0
radius:
base: 4.0
per-level: 0.0
per-level: 1.0
ratio:
base: 30.0
per-level: 10.0

View File

@ -8,17 +8,17 @@ lore:
material: LEATHER_BOOTS
duration:
base: 2.0
per-level: 0.3
per-level: 1.3
max: 10.0
min: 2.0
mana:
base: 8.0
per-level: 3.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:
base: 20.0
per-level: 0.0
per-level: 1.0

View File

@ -3,13 +3,13 @@ lore:
- You deal &c{extra}% &7more damage when on fire.
material: FLINT_AND_STEEL
mana:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:

View File

@ -10,24 +10,24 @@ lore:
material: FIRE_CHARGE
duration:
base: 8.0
per-level: 0.0
per-level: 1.0
damage:
base: 5.0
per-level: 3.0
ignite:
base: 2.0
per-level: 0.1
per-level: 1.1
mana:
base: 15.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
count:
base: 4.0
per-level: 0.0
per-level: 1.0
cooldown:
base: 9.0
per-level: -0.1

View File

@ -13,13 +13,13 @@ damage:
per-level: 3.0
ignite:
base: 2.0
per-level: 0.1
per-level: 1.1
mana:
base: 15.0
per-level: 2.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -16,13 +16,13 @@ damage:
per-level: 3.0
ignite:
base: 2.0
per-level: 0.1
per-level: 1.1
mana:
base: 15.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -13,8 +13,8 @@ mana:
base: 8.0
per-level: 3.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:
@ -27,4 +27,4 @@ cooldown:
min: 5.0
radius:
base: 7.0
per-level: 0.0
per-level: 1.0

View File

@ -10,8 +10,8 @@ mana:
base: 4.0
per-level: 2.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
heal:

View File

@ -16,16 +16,16 @@ redirect:
min: 20.0
duration:
base: 7.0
per-level: 0.0
per-level: 1.0
mana:
base: 15.0
per-level: 1.5
low:
base: 10.0
per-level: 0.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -16,10 +16,10 @@ mana:
per-level: 2.0
slow:
base: 4.0
per-level: 0.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -10,8 +10,8 @@ mana:
base: 4.0
per-level: 2.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
heal:

View File

@ -16,23 +16,23 @@ lore:
material: WITHER_SKELETON_SKULL
duration:
base: 10.0
per-level: 0.1
per-level: 1.1
mana:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:
base: 30.0
per-level: 0.0
per-level: 1.0
stun:
base: 0.4
per-level: 0.03
base: 2.4
per-level: 1.03
ratio:
base: 10.0
per-level: 5.0

View File

@ -9,13 +9,13 @@ mana:
base: 8.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
extra:
base: 50.0
per-level: 20.0
cooldown:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0

View File

@ -9,15 +9,15 @@ lore:
material: MAGENTA_DYE
duration:
base: 3.0
per-level: 0.1
per-level: 1.1
max: 6.0
min: 3.0
mana:
base: 20.0
per-level: 2.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -10,8 +10,8 @@ mana:
base: 8.0
per-level: 3.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown:

View File

@ -16,8 +16,8 @@ mana:
base: 4.0
per-level: 1.0
stamina:
base: 0.0
per-level: 0.0
base: 2.0
per-level: 1.0
max: 0.0
min: 0.0
cooldown: