mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-23 00:05:52 +01:00
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:
commit
af2c68054e
@ -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"));
|
||||
|
@ -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")));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
});
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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," +
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
@ -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: {}
|
@ -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: {}
|
@ -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: {}
|
@ -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: {}
|
@ -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: {}
|
@ -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: {}
|
@ -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}'
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user