mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2025-02-16 13:41:40 +01:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f79a66df80
@ -176,8 +176,8 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
public void setupRemovableTrigger() {
|
public void setupRemovableTrigger() {
|
||||||
//We remove all the stats and buffs associated to triggers.
|
//We remove all the stats and buffs associated to triggers.
|
||||||
getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals));
|
||||||
getMMOPlayerData().getSkillModifierMap().getInstances().forEach(skillModifierInstance -> skillModifierInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
getMMOPlayerData().getSkillModifierMap().getInstances().forEach(skillModifierInstance -> skillModifierInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals));
|
||||||
|
|
||||||
if (profess.hasExperienceTable())
|
if (profess.hasExperienceTable())
|
||||||
profess.getExperienceTable().claimRemovableTrigger(this, profess);
|
profess.getExperienceTable().claimRemovableTrigger(this, profess);
|
||||||
@ -250,7 +250,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
Iterator<StatModifier> iter = instance.getModifiers().iterator();
|
Iterator<StatModifier> iter = instance.getModifiers().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
StatModifier modifier = iter.next();
|
StatModifier modifier = iter.next();
|
||||||
if (modifier.getKey().startsWith(StatTrigger.TRIGGER_PREFIX)) iter.remove();
|
if (modifier.getKey().startsWith(StatTrigger.STAT_MODIFIER_KEY)) iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +357,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If the item is unlocked by the player
|
* @return If the item is unlocked by the player
|
||||||
* This is used for skills that can be locked & unlocked.
|
* This is used for skills that can be locked & unlocked.
|
||||||
*/
|
*/
|
||||||
public boolean hasUnlocked(Unlockable unlockable) {
|
public boolean hasUnlocked(Unlockable unlockable) {
|
||||||
return unlockable.isUnlockedByDefault() || unlockedItems.contains(unlockable.getUnlockNamespacedKey());
|
return unlockable.isUnlockedByDefault() || unlockedItems.contains(unlockable.getUnlockNamespacedKey());
|
||||||
@ -1017,7 +1017,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If the PlayerEnterCastingModeEvent successfully put the player
|
* @return If the PlayerEnterCastingModeEvent successfully put the player
|
||||||
* into casting mode, otherwise if the event is cancelled, returns false.
|
* into casting mode, otherwise if the event is cancelled, returns false.
|
||||||
*/
|
*/
|
||||||
public boolean setSkillCasting() {
|
public boolean setSkillCasting() {
|
||||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||||
@ -1036,7 +1036,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If player successfully left skill casting i.e the Bukkit
|
* @return If player successfully left skill casting i.e the Bukkit
|
||||||
* event has not been cancelled
|
* event has not been cancelled
|
||||||
*/
|
*/
|
||||||
public boolean leaveSkillCasting() {
|
public boolean leaveSkillCasting() {
|
||||||
return leaveSkillCasting(false);
|
return leaveSkillCasting(false);
|
||||||
@ -1045,7 +1045,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
/**
|
/**
|
||||||
* @param skipEvent Skip firing the exit event
|
* @param skipEvent Skip firing the exit event
|
||||||
* @return If player successfully left skill casting i.e the Bukkit
|
* @return If player successfully left skill casting i.e the Bukkit
|
||||||
* event has not been cancelled
|
* event has not been cancelled
|
||||||
*/
|
*/
|
||||||
public boolean leaveSkillCasting(boolean skipEvent) {
|
public boolean leaveSkillCasting(boolean skipEvent) {
|
||||||
Validate.isTrue(isCasting(), "Player not in casting mode");
|
Validate.isTrue(isCasting(), "Player not in casting mode");
|
||||||
@ -1161,6 +1161,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
boundSkills.forEach((slot, info) -> info.close());
|
boundSkills.forEach((slot, info) -> info.close());
|
||||||
boundSkills.clear();
|
boundSkills.clear();
|
||||||
setupRemovableTrigger();
|
setupRemovableTrigger();
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
if (isOnline()) getStats().updateStats();
|
if (isOnline()) getStats().updateStats();
|
||||||
}
|
}
|
||||||
@ -1187,15 +1188,12 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
*/
|
*/
|
||||||
public void bindSkill(int slot, @NotNull ClassSkill skill) {
|
public void bindSkill(int slot, @NotNull ClassSkill skill) {
|
||||||
Validate.notNull(skill, "Skill cannot be null");
|
Validate.notNull(skill, "Skill cannot be null");
|
||||||
|
if (slot < 0) return;
|
||||||
|
|
||||||
if (slot >= 0) {
|
// Unbinds the previous skill (important for passive skills)
|
||||||
|
unbindSkill(slot);
|
||||||
// Unbinds the previous skill (important for passive skills)
|
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
|
||||||
unbindSkill(slot);
|
boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this));
|
||||||
|
|
||||||
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
|
|
||||||
boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbindSkill(int slot) {
|
public void unbindSkill(int slot) {
|
||||||
@ -1221,7 +1219,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
* checks if they could potentially upgrade to one of these
|
* checks if they could potentially upgrade to one of these
|
||||||
*
|
*
|
||||||
* @return If the player can change its current class to
|
* @return If the player can change its current class to
|
||||||
* a subclass
|
* a subclass
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean canChooseSubclass() {
|
public boolean canChooseSubclass() {
|
||||||
|
@ -1,36 +1,30 @@
|
|||||||
package net.Indyuce.mmocore.api.player.attribute;
|
package net.Indyuce.mmocore.api.player.attribute;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||||
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
|
import io.lumine.mythic.lib.api.stat.api.InstanceModifier;
|
||||||
import io.lumine.mythic.lib.player.modifier.ModifierSource;
|
import io.lumine.mythic.lib.player.modifier.ModifierSource;
|
||||||
import io.lumine.mythic.lib.player.modifier.ModifierType;
|
import io.lumine.mythic.lib.player.modifier.ModifierType;
|
||||||
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
|
|
||||||
import io.lumine.mythic.lib.util.configobject.ConfigObject;
|
import io.lumine.mythic.lib.util.configobject.ConfigObject;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.util.UUID;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class AttributeModifier extends PlayerModifier {
|
public class AttributeModifier extends InstanceModifier {
|
||||||
private final String attribute;
|
private final String attribute;
|
||||||
private final double value;
|
|
||||||
private final ModifierType type;
|
|
||||||
|
|
||||||
private static final DecimalFormat oneDigit = MythicLib.plugin.getMMOConfig().newDecimalFormat("0.#");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flat attribute modifier (simplest modifier you can think about)
|
* Flat attribute modifier (simplest modifier you can think about)
|
||||||
*/
|
*/
|
||||||
public AttributeModifier(String key, String attribute, double value) {
|
public AttributeModifier(String key, String attribute, double value) {
|
||||||
this(key, attribute, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER);
|
super(key, value);
|
||||||
|
|
||||||
|
this.attribute = attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute modifier given by an external mecanic, like a party buff, item set bonuses,
|
* Attribute modifier given by an external mechanic, like a party buff, item
|
||||||
* skills or abilities... Anything apart from items and armor.
|
* set bonuses, skills or abilities... Anything apart from items and armor.
|
||||||
*/
|
*/
|
||||||
public AttributeModifier(String key, String attribute, double value, ModifierType type) {
|
public AttributeModifier(String key, String attribute, double value, ModifierType type) {
|
||||||
this(key, attribute, value, type, EquipmentSlot.OTHER, ModifierSource.OTHER);
|
this(key, attribute, value, type, EquipmentSlot.OTHER, ModifierSource.OTHER);
|
||||||
@ -47,11 +41,23 @@ public class AttributeModifier extends PlayerModifier {
|
|||||||
* @param source Type of the item granting the stat modifier
|
* @param source Type of the item granting the stat modifier
|
||||||
*/
|
*/
|
||||||
public AttributeModifier(String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
|
public AttributeModifier(String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
|
||||||
super(key, slot, source);
|
this(UUID.randomUUID(), key, attribute, value, type, slot, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute modifier given by an item, either a weapon or an armor piece.
|
||||||
|
*
|
||||||
|
* @param key Player modifier key
|
||||||
|
* @param attribute Attribute being modified
|
||||||
|
* @param value Value of stat modifier
|
||||||
|
* @param type Is the modifier flat or multiplicative
|
||||||
|
* @param slot Slot of the item granting the stat modifier
|
||||||
|
* @param source Type of the item granting the stat modifier
|
||||||
|
*/
|
||||||
|
public AttributeModifier(UUID uniqueId, String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
|
||||||
|
super(uniqueId, key, slot, source, value, type);
|
||||||
|
|
||||||
this.attribute = attribute;
|
this.attribute = attribute;
|
||||||
this.value = value;
|
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,22 +68,14 @@ public class AttributeModifier extends PlayerModifier {
|
|||||||
* @param str The string to be parsed
|
* @param str The string to be parsed
|
||||||
*/
|
*/
|
||||||
public AttributeModifier(String key, String attribute, String str) {
|
public AttributeModifier(String key, String attribute, String str) {
|
||||||
super(key, EquipmentSlot.OTHER, ModifierSource.OTHER);
|
super(key, EquipmentSlot.OTHER, ModifierSource.OTHER, str);
|
||||||
|
|
||||||
Validate.notNull(str, "String cannot be null");
|
|
||||||
Validate.notEmpty(str, "String cannot be empty");
|
|
||||||
|
|
||||||
type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
|
|
||||||
value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
|
|
||||||
this.attribute = attribute;
|
this.attribute = attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AttributeModifier(ConfigObject object) {
|
public AttributeModifier(ConfigObject object) {
|
||||||
super(object.getString("key"), EquipmentSlot.OTHER, ModifierSource.OTHER);
|
super(object);
|
||||||
|
|
||||||
String str = Objects.requireNonNull(object.getString("value"));
|
|
||||||
type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
|
|
||||||
value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
|
|
||||||
this.attribute = object.getString("attribute");
|
this.attribute = object.getString("attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,14 +83,6 @@ public class AttributeModifier extends PlayerModifier {
|
|||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModifierType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to multiply some existing stat modifier by a constant, usually an
|
* Used to multiply some existing stat modifier by a constant, usually an
|
||||||
* integer, for instance when MMOCore party modifiers scale with the
|
* integer, for instance when MMOCore party modifiers scale with the
|
||||||
@ -101,8 +91,8 @@ public class AttributeModifier extends PlayerModifier {
|
|||||||
* @param coef The multiplicative constant
|
* @param coef The multiplicative constant
|
||||||
* @return A new instance of StatModifier with modified value
|
* @return A new instance of StatModifier with modified value
|
||||||
*/
|
*/
|
||||||
public StatModifier multiply(double coef) {
|
public AttributeModifier multiply(double coef) {
|
||||||
return new StatModifier(getKey(), attribute, value * coef, type, getSlot(), getSource());
|
return new AttributeModifier(getUniqueId(), getKey(), attribute, value * coef, type, getSlot(), getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,9 +106,4 @@ public class AttributeModifier extends PlayerModifier {
|
|||||||
PlayerData playerData = PlayerData.get(mmoPlayerData);
|
PlayerData playerData = PlayerData.get(mmoPlayerData);
|
||||||
playerData.getAttributes().getInstance(attribute).removeModifier(getKey());
|
playerData.getAttributes().getInstance(attribute).removeModifier(getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return oneDigit.format(value) + (type == io.lumine.mythic.lib.player.modifier.ModifierType.RELATIVE ? "%" : "");
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -113,6 +113,7 @@ public class PlayerAttributes {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO have it extend ModifiedInstance
|
||||||
public class AttributeInstance {
|
public class AttributeInstance {
|
||||||
private int spent;
|
private int spent;
|
||||||
|
|
||||||
@ -223,10 +224,9 @@ public class PlayerAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setBaseAttribute(String id, int value) {
|
public void setBaseAttribute(String id, int value) {
|
||||||
getInstances().forEach(ins -> {
|
AttributeInstance ins = instances.get(id);
|
||||||
if (ins.getId().equals(id))
|
if (ins != null) ins.setBase(value);
|
||||||
ins.setBase(value);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import io.lumine.mythic.lib.gson.JsonObject;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||||
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.player.ClassDataContainer;
|
import net.Indyuce.mmocore.player.ClassDataContainer;
|
||||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||||
@ -304,7 +305,8 @@ public class SavedClassInformation implements ClassDataContainer {
|
|||||||
* Resets information which much be reset after everything is saved.
|
* Resets information which much be reset after everything is saved.
|
||||||
*/
|
*/
|
||||||
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
|
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
|
||||||
player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
|
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll())
|
||||||
|
player.getAttributes().getInstance(attribute).setBase(0);
|
||||||
player.clearSkillTreePoints();
|
player.clearSkillTreePoints();
|
||||||
player.clearNodeLevels();
|
player.clearNodeLevels();
|
||||||
player.clearNodeStates();
|
player.clearNodeStates();
|
||||||
@ -327,7 +329,10 @@ public class SavedClassInformation implements ClassDataContainer {
|
|||||||
player.bindSkill(slot, profess.getSkill(boundSkills.get(slot)));
|
player.bindSkill(slot, profess.getSkill(boundSkills.get(slot)));
|
||||||
|
|
||||||
skillLevels.forEach(player::setSkillLevel);
|
skillLevels.forEach(player::setSkillLevel);
|
||||||
attributeLevels.forEach((id, pts) -> player.getAttributes().setBaseAttribute(id, pts));
|
attributeLevels.forEach((id, pts) -> {
|
||||||
|
final PlayerAttributes.AttributeInstance ins = player.getAttributes().getInstance(id);
|
||||||
|
if (ins != null) ins.setBase(pts);
|
||||||
|
});
|
||||||
|
|
||||||
// Careful, the global points must not be forgotten.
|
// Careful, the global points must not be forgotten.
|
||||||
player.setSkillTreePoints("global", skillTreePoints.getOrDefault("global", 0));
|
player.setSkillTreePoints("global", skillTreePoints.getOrDefault("global", 0));
|
||||||
@ -342,7 +347,6 @@ public class SavedClassInformation implements ClassDataContainer {
|
|||||||
// Add the values to the times claimed table and claims the corresponding stat triggers.
|
// Add the values to the times claimed table and claims the corresponding stat triggers.
|
||||||
nodeTimesClaimed.forEach((str, val) -> player.setClaims(str, val));
|
nodeTimesClaimed.forEach((str, val) -> player.setClaims(str, val));
|
||||||
|
|
||||||
|
|
||||||
// Unload current class information
|
// Unload current class information
|
||||||
player.unloadClassInfo(profess);
|
player.unloadClassInfo(profess);
|
||||||
|
|
||||||
|
@ -12,11 +12,6 @@ import net.Indyuce.mmocore.MMOCore;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.player.stats.StatInfo;
|
import net.Indyuce.mmocore.player.stats.StatInfo;
|
||||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PlayerStats {
|
public class PlayerStats {
|
||||||
private final PlayerData data;
|
private final PlayerData data;
|
||||||
@ -78,6 +73,8 @@ public class PlayerStats {
|
|||||||
* see {@link PlayerData#reload()} for more info
|
* see {@link PlayerData#reload()} for more info
|
||||||
*/
|
*/
|
||||||
public synchronized void updateStats() {
|
public synchronized void updateStats() {
|
||||||
|
|
||||||
|
// Update player stats
|
||||||
for (String stat : MMOCore.plugin.statManager.getRegistered()) {
|
for (String stat : MMOCore.plugin.statManager.getRegistered()) {
|
||||||
final StatInstance instance = getMap().getInstance(stat);
|
final StatInstance instance = getMap().getInstance(stat);
|
||||||
final StatInstance.ModifierPacket packet = instance.newPacket();
|
final StatInstance.ModifierPacket packet = instance.newPacket();
|
||||||
@ -94,22 +91,17 @@ public class PlayerStats {
|
|||||||
packet.runUpdate();
|
packet.runUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Updates the player's unbindable passive skills.
|
||||||
* This is here because it requires updates for the same reasons
|
|
||||||
* as statistics (when the player level changes, when his class
|
|
||||||
* changes, when he logs on..)
|
|
||||||
*
|
|
||||||
* This updates the player's PASSIVE skills
|
|
||||||
*/
|
|
||||||
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
|
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
|
||||||
|
|
||||||
skillMap.removeModifiers("MMOCorePassiveSkillNotBound");
|
skillMap.removeModifiers("MMOCorePassiveSkillNotBound");
|
||||||
data.getProfess().getSkills()
|
data.getProfess().getSkills().stream()
|
||||||
.stream()
|
.filter((classSkill) -> !classSkill.needsBound() && classSkill.getSkill().getTrigger().isPassive() && data.hasUnlocked(classSkill) && data.hasUnlockedLevel(classSkill))
|
||||||
.filter((classSkill) -> !classSkill.needsBound()&&classSkill.getSkill().getTrigger().isPassive() && data.hasUnlocked(classSkill) && data.hasUnlockedLevel(classSkill))
|
|
||||||
.forEach(classSkill -> skillMap.addModifier(classSkill.toPassive(data)));
|
.forEach(classSkill -> skillMap.addModifier(classSkill.toPassive(data)));
|
||||||
|
|
||||||
// This updates the player's class SCRIPTS
|
/*
|
||||||
|
* Updates the player's class scripts, which act just
|
||||||
|
* like non-bindable passive skills.
|
||||||
|
*/
|
||||||
skillMap.removeModifiers("MMOCoreClassScript");
|
skillMap.removeModifiers("MMOCoreClassScript");
|
||||||
for (PassiveSkill script : data.getProfess().getScripts())
|
for (PassiveSkill script : data.getProfess().getScripts())
|
||||||
skillMap.addModifier(script);
|
skillMap.addModifier(script);
|
||||||
|
@ -12,11 +12,9 @@ import net.Indyuce.mmocore.skill.RegisteredSkill;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class SkillModifierTrigger extends Trigger implements Removable {
|
public class SkillModifierTrigger extends Trigger implements Removable {
|
||||||
private final SkillModifier mod;
|
private final SkillModifier mod;
|
||||||
private final String buffKey = TRIGGER_PREFIX + "." + UUID.randomUUID();
|
|
||||||
private final double amount;
|
private final double amount;
|
||||||
|
|
||||||
public SkillModifierTrigger(MMOLineConfig config) {
|
public SkillModifierTrigger(MMOLineConfig config) {
|
||||||
@ -34,7 +32,7 @@ public class SkillModifierTrigger extends Trigger implements Removable {
|
|||||||
if (skill.matchesFormula(formula))
|
if (skill.matchesFormula(formula))
|
||||||
targetSkills.add(skill.getHandler());
|
targetSkills.add(skill.getHandler());
|
||||||
|
|
||||||
mod = new SkillModifier(buffKey, skillModifier, targetSkills, amount, type);
|
mod = new SkillModifier(Trigger.STAT_MODIFIER_KEY, skillModifier, targetSkills, amount, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SkillHandler<?>> getTargetSkills() {
|
public List<SkillHandler<?>> getTargetSkills() {
|
||||||
|
@ -7,12 +7,9 @@ import net.Indyuce.mmocore.api.player.PlayerData;
|
|||||||
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
|
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class StatTrigger extends Trigger implements Removable {
|
public class StatTrigger extends Trigger implements Removable {
|
||||||
private final StatModifier statModifier;
|
private final StatModifier modifier;
|
||||||
private final String stat;
|
private final String stat;
|
||||||
private final String modifierKey = TRIGGER_PREFIX + "." + UUID.randomUUID();
|
|
||||||
private final double amount;
|
private final double amount;
|
||||||
|
|
||||||
public StatTrigger(MMOLineConfig config) {
|
public StatTrigger(MMOLineConfig config) {
|
||||||
@ -25,14 +22,14 @@ public class StatTrigger extends Trigger implements Removable {
|
|||||||
Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE"));
|
Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE"));
|
||||||
stat = config.getString("stat");
|
stat = config.getString("stat");
|
||||||
amount = config.getDouble("amount");
|
amount = config.getDouble("amount");
|
||||||
statModifier = new StatModifier(modifierKey, stat, amount, ModifierType.valueOf(type));
|
modifier = new StatModifier(Trigger.STAT_MODIFIER_KEY, stat, amount, ModifierType.valueOf(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(PlayerData player) {
|
public void apply(PlayerData player) {
|
||||||
StatModifier prevModifier = player.getMMOPlayerData().getStatMap().getInstance(stat).getModifier(modifierKey);
|
StatModifier prevModifier = player.getMMOPlayerData().getStatMap().getInstance(stat).getModifier(modifier.getUniqueId());
|
||||||
if (prevModifier == null)
|
if (prevModifier == null)
|
||||||
statModifier.register(player.getMMOPlayerData());
|
modifier.register(player.getMMOPlayerData());
|
||||||
else {
|
else {
|
||||||
prevModifier.unregister(player.getMMOPlayerData());
|
prevModifier.unregister(player.getMMOPlayerData());
|
||||||
prevModifier.add(amount).register(player.getMMOPlayerData());
|
prevModifier.add(amount).register(player.getMMOPlayerData());
|
||||||
@ -41,6 +38,6 @@ public class StatTrigger extends Trigger implements Removable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(PlayerData playerData) {
|
public void remove(PlayerData playerData) {
|
||||||
playerData.getMMOPlayerData().getStatMap().getInstance(stat).remove(modifierKey);
|
modifier.unregister(playerData.getMMOPlayerData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import org.bukkit.Bukkit;
|
|||||||
|
|
||||||
public abstract class Trigger {
|
public abstract class Trigger {
|
||||||
|
|
||||||
public static String TRIGGER_PREFIX = "mmocore_trigger";
|
public static String STAT_MODIFIER_KEY = "mmocore_trigger";
|
||||||
private final long delay;
|
private final long delay;
|
||||||
|
|
||||||
public Trigger(MMOLineConfig config) {
|
public Trigger(MMOLineConfig config) {
|
||||||
|
@ -12,6 +12,7 @@ import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
|||||||
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.party.AbstractParty;
|
import net.Indyuce.mmocore.party.AbstractParty;
|
||||||
|
import net.Indyuce.mmocore.skill.CastableSkill;
|
||||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -58,10 +59,11 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
|||||||
public String onRequest(OfflinePlayer player, String identifier) {
|
public String onRequest(OfflinePlayer player, String identifier) {
|
||||||
if (!PlayerData.has(player.getUniqueId()))
|
if (!PlayerData.has(player.getUniqueId()))
|
||||||
return null;
|
return null;
|
||||||
|
final PlayerData playerData = PlayerData.get(player);
|
||||||
|
|
||||||
PlayerData playerData = PlayerData.get(player);
|
|
||||||
if (identifier.equals("mana_icon"))
|
if (identifier.equals("mana_icon"))
|
||||||
return playerData.getProfess().getManaDisplay().getIcon();
|
return playerData.getProfess().getManaDisplay().getIcon();
|
||||||
|
|
||||||
if (identifier.equals("mana_name"))
|
if (identifier.equals("mana_name"))
|
||||||
return playerData.getProfess().getManaDisplay().getName();
|
return playerData.getProfess().getManaDisplay().getName();
|
||||||
|
|
||||||
@ -72,15 +74,19 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
|||||||
String id = identifier.substring(12);
|
String id = identifier.substring(12);
|
||||||
RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(id), "Could not find skill with ID '" + id + "'");
|
RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(id), "Could not find skill with ID '" + id + "'");
|
||||||
return String.valueOf(playerData.getSkillLevel(skill));
|
return String.valueOf(playerData.getSkillLevel(skill));
|
||||||
} else if (identifier.startsWith("skill_modifier_") || identifier.startsWith("skill_parameter_")) {
|
}
|
||||||
String[] ids = (identifier.startsWith("skill_modifier_") ? identifier.substring(15) : identifier.substring(16)).split(":");
|
|
||||||
String parameterId = ids[0];
|
else if (identifier.startsWith("skill_modifier_") || identifier.startsWith("skill_parameter_")) {
|
||||||
String skillId = ids[1];
|
final String[] ids = (identifier.startsWith("skill_modifier_") ? identifier.substring(15) : identifier.substring(16)).split(":");
|
||||||
RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(skillId), "Could not find skill with ID '" + skillId + "'");
|
final String parameterId = ids[0];
|
||||||
ClassSkill classSkill = playerData.getProfess().getSkill(skill);
|
final String skillId = ids[1];
|
||||||
double value = classSkill.toCastable(playerData).getParameter(parameterId);
|
final RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(skillId), "Could not find skill with ID '" + skillId + "'");
|
||||||
|
final CastableSkill castable = playerData.getProfess().getSkill(skill).toCastable(playerData);
|
||||||
|
final double value = playerData.getMMOPlayerData().getSkillModifierMap().calculateValue(castable, parameterId);
|
||||||
return MythicLib.plugin.getMMOConfig().decimal.format(value);
|
return MythicLib.plugin.getMMOConfig().decimal.format(value);
|
||||||
} else if (identifier.startsWith("attribute_points_spent_")) {
|
}
|
||||||
|
|
||||||
|
else if (identifier.startsWith("attribute_points_spent_")) {
|
||||||
String attributeId = identifier.substring(31);
|
String attributeId = identifier.substring(31);
|
||||||
PlayerAttributes.AttributeInstance attributeInstance = Objects.requireNonNull(playerData.getAttributes().getInstance(attributeId), "Could not find attribute with ID '" + attributeId + "'");
|
PlayerAttributes.AttributeInstance attributeInstance = Objects.requireNonNull(playerData.getAttributes().getInstance(attributeId), "Could not find attribute with ID '" + attributeId + "'");
|
||||||
return String.valueOf(attributeInstance.getSpent());
|
return String.valueOf(attributeInstance.getSpent());
|
||||||
|
@ -109,7 +109,7 @@ public class AttributeView extends EditableInventory {
|
|||||||
playerData.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
|
playerData.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
|
||||||
playerData.giveAttributePoints(spent);
|
playerData.giveAttributePoints(spent);
|
||||||
playerData.giveAttributeReallocationPoints(-1);
|
playerData.giveAttributeReallocationPoints(-1);
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("attribute-points-reallocated", "points", "" + playerData.getAttributePoints()).send(player);
|
MMOCore.plugin.configManager.getSimpleMessage("attribute-points-reallocated", "points", String.valueOf(playerData.getAttributePoints())).send(player);
|
||||||
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_ATTRIBUTES).playTo(getPlayer());
|
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_ATTRIBUTES).playTo(getPlayer());
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,6 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
|
|||||||
inv.setItem(slot, display);
|
inv.setItem(slot, display);
|
||||||
} else for (int j = 0; j < slots.size(); j++)
|
} else for (int j = 0; j < slots.size(); j++)
|
||||||
inv.setItem(slots.get(j), display(generated, j));
|
inv.setItem(slots.get(j), display(generated, j));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDifferentDisplay() {
|
public boolean hasDifferentDisplay() {
|
||||||
@ -125,7 +124,7 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ItemStack display(T inv) {
|
public ItemStack display(T inv) {
|
||||||
return display(inv, modelData);
|
return display(inv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ -263,7 +263,8 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
lore.add(holders.apply(inv.getPlayer(), str));
|
lore.add(holders.apply(inv.getPlayer(), str));
|
||||||
});
|
});
|
||||||
meta.setLore(lore);
|
meta.setLore(lore);
|
||||||
meta.setDisplayName(node.getName());
|
final String name = meta.getDisplayName();
|
||||||
|
meta.setDisplayName(name == null || name.isEmpty() ? node.getName() : name);
|
||||||
}
|
}
|
||||||
//If it is path we remove the display name and the lore.
|
//If it is path we remove the display name and the lore.
|
||||||
else {
|
else {
|
||||||
@ -306,8 +307,8 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
SkillTreeStatus status = inv.getPlayerData().getNodeStatus(node);
|
SkillTreeStatus status = inv.getPlayerData().getNodeStatus(node);
|
||||||
holders.register("current-state", statusNames.getOrDefault(status, status.name()));
|
holders.register("current-state", statusNames.getOrDefault(status, status.name()));
|
||||||
holders.register("max-level", node.getMaxLevel());
|
holders.register("max-level", node.getMaxLevel());
|
||||||
|
holders.register("name", node.getName());
|
||||||
holders.register("max-children", node.getMaxChildren());
|
holders.register("max-children", node.getMaxChildren());
|
||||||
holders.register("size", node.getSize());
|
|
||||||
holders.register("point-consumed", node.getSkillTreePointsConsumed());
|
holders.register("point-consumed", node.getSkillTreePointsConsumed());
|
||||||
holders.register("display-type", node.getNodeType());
|
holders.register("display-type", node.getNodeType());
|
||||||
} else {
|
} else {
|
||||||
|
@ -207,7 +207,7 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge with {@link net.Indyuce.mmocore.api.ConfigMessage}
|
* @deprecated TODO Merge with {@link net.Indyuce.mmocore.api.ConfigMessage}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public SimpleMessage getSimpleMessage(String key, String... placeholders) {
|
public SimpleMessage getSimpleMessage(String key, String... placeholders) {
|
||||||
@ -218,7 +218,7 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge with {@link net.Indyuce.mmocore.api.ConfigMessage}
|
* @deprecated TODO Merge with {@link net.Indyuce.mmocore.api.ConfigMessage}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static class SimpleMessage {
|
public static class SimpleMessage {
|
||||||
|
@ -81,6 +81,8 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
|||||||
if (guild != null) getData().setGuild(guild.hasMember(getData().getUniqueId()) ? guild : null);
|
if (guild != null) getData().setGuild(guild.hasMember(getData().getUniqueId()) ? guild : null);
|
||||||
}
|
}
|
||||||
if (!isEmpty(result.getString("attributes"))) getData().getAttributes().load(result.getString("attributes"));
|
if (!isEmpty(result.getString("attributes"))) getData().getAttributes().load(result.getString("attributes"));
|
||||||
|
if (getData().isOnline())
|
||||||
|
MMOCore.plugin.attributeManager.getAll().forEach(attribute -> getData().getAttributes().getInstance(attribute).updateStats());
|
||||||
if (!isEmpty(result.getString("professions")))
|
if (!isEmpty(result.getString("professions")))
|
||||||
getData().getCollectionSkills().load(result.getString("professions"));
|
getData().getCollectionSkills().load(result.getString("professions"));
|
||||||
if (!isEmpty(result.getString("quests"))) getData().getQuestData().load(result.getString("quests"));
|
if (!isEmpty(result.getString("quests"))) getData().getQuestData().load(result.getString("quests"));
|
||||||
|
@ -64,6 +64,8 @@ public class YAMLPlayerDataHandler extends YAMLSynchronizedDataHandler<PlayerDat
|
|||||||
}
|
}
|
||||||
if (config.contains("attribute"))
|
if (config.contains("attribute"))
|
||||||
data.getAttributes().load(config.getConfigurationSection("attribute"));
|
data.getAttributes().load(config.getConfigurationSection("attribute"));
|
||||||
|
if (data.isOnline())
|
||||||
|
MMOCore.plugin.attributeManager.getAll().forEach(attribute -> data.getAttributes().getInstance(attribute).updateStats());
|
||||||
if (config.contains("profession"))
|
if (config.contains("profession"))
|
||||||
data.getCollectionSkills().load(config.getConfigurationSection("profession"));
|
data.getCollectionSkills().load(config.getConfigurationSection("profession"));
|
||||||
if (config.contains("quest"))
|
if (config.contains("quest"))
|
||||||
|
@ -8,8 +8,6 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* All the class-specific information i.e information being saved
|
* All the class-specific information i.e information being saved
|
||||||
* in {@link SavedClassInformation} when a player changes its current class.
|
* in {@link SavedClassInformation} when a player changes its current class.
|
||||||
*
|
|
||||||
* TODO move {@link SavedClassInformation} method to ClassDataContainer
|
|
||||||
*/
|
*/
|
||||||
public interface ClassDataContainer {
|
public interface ClassDataContainer {
|
||||||
|
|
||||||
|
@ -65,15 +65,15 @@ public class CastableSkill extends Skill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mana cost
|
// Mana cost
|
||||||
if (playerData.getMana() < getParameter("mana")) {
|
if (playerData.getMana() < skillMeta.getParameter("mana")) {
|
||||||
if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana",
|
if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana",
|
||||||
"mana-required", MythicLib.plugin.getMMOConfig().decimal.format((getParameter("mana") - playerData.getMana())),
|
"mana-required", MythicLib.plugin.getMMOConfig().decimal.format((skillMeta.getParameter("mana") - playerData.getMana())),
|
||||||
"mana", playerData.getProfess().getManaDisplay().getName()).send(playerData.getPlayer());
|
"mana", playerData.getProfess().getManaDisplay().getName()).send(playerData.getPlayer());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stamina cost
|
// Stamina cost
|
||||||
if (playerData.getStamina() < getParameter("stamina")) {
|
if (playerData.getStamina() < skillMeta.getParameter("stamina")) {
|
||||||
|
|
||||||
if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(playerData.getPlayer());
|
if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(playerData.getPlayer());
|
||||||
return false;
|
return false;
|
||||||
@ -95,11 +95,11 @@ public class CastableSkill extends Skill {
|
|||||||
|
|
||||||
// Cooldown
|
// Cooldown
|
||||||
double flatCooldownReduction = Math.max(0, Math.min(1, skillMeta.getCaster().getStat("COOLDOWN_REDUCTION") / 100));
|
double flatCooldownReduction = Math.max(0, Math.min(1, skillMeta.getCaster().getStat("COOLDOWN_REDUCTION") / 100));
|
||||||
CooldownInfo cooldownHandler = skillMeta.getCaster().getData().getCooldownMap().applyCooldown(this, getParameter("cooldown"));
|
CooldownInfo cooldownHandler = skillMeta.getCaster().getData().getCooldownMap().applyCooldown(this, skillMeta.getParameter("cooldown"));
|
||||||
cooldownHandler.reduceInitialCooldown(flatCooldownReduction);
|
cooldownHandler.reduceInitialCooldown(flatCooldownReduction);
|
||||||
|
|
||||||
casterData.giveMana(-getParameter("mana"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
|
casterData.giveMana(-skillMeta.getParameter("mana"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
|
||||||
casterData.giveStamina(-getParameter("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
|
casterData.giveStamina(-skillMeta.getParameter("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getTrigger().isPassive())
|
if (!getTrigger().isPassive())
|
||||||
|
@ -4,6 +4,8 @@ import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
|||||||
import io.lumine.mythic.lib.skill.SkillMetadata;
|
import io.lumine.mythic.lib.skill.SkillMetadata;
|
||||||
import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
||||||
import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
|
import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
|
||||||
|
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
|
||||||
|
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -33,7 +35,7 @@ public class Neptune_Gift extends SkillHandler<SimpleSkillResult> implements Lis
|
|||||||
if (skill == null)
|
if (skill == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.setAmount(event.getAmount() * (1 + skill.getTriggeredSkill().getParameter("extra") / 100));
|
event.setAmount(event.getAmount() * (1 + event.getData().getMMOPlayerData().getSkillModifierMap().calculateValue(skill.getTriggeredSkill(), "extra") / 100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
private final ExperienceTable experienceTable;
|
private final ExperienceTable experienceTable;
|
||||||
|
|
||||||
// The max level the skill tree node can have and the max amount of children it can have.
|
// The max level the skill tree node can have and the max amount of children it can have.
|
||||||
private final int maxLevel, maxChildren, size;
|
private final int maxLevel, maxChildren;
|
||||||
private final List<SkillTreeNode> children = new ArrayList<>();
|
private final List<SkillTreeNode> children = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +77,6 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
||||||
size = Objects.requireNonNull(config.getInt("size"));
|
|
||||||
isRoot = config.getBoolean("is-root", false);
|
isRoot = config.getBoolean("is-root", false);
|
||||||
skillTreePointsConsumed = config.getInt("point-consumed", 1);
|
skillTreePointsConsumed = config.getInt("point-consumed", 1);
|
||||||
permissionRequired = config.getString("permission-required");
|
permissionRequired = config.getString("permission-required");
|
||||||
@ -86,8 +85,8 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
for (String key : config.getConfigurationSection("lores").getKeys(false))
|
for (String key : config.getConfigurationSection("lores").getKeys(false))
|
||||||
try {
|
try {
|
||||||
lores.put(Integer.parseInt(key), config.getStringList("lores." + key));
|
lores.put(Integer.parseInt(key), config.getStringList("lores." + key));
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException exception) {
|
||||||
throw new RuntimeException("You must only specifiy integers in lores.");
|
throw new RuntimeException("You shall only specify integers in the 'lores' config section");
|
||||||
}
|
}
|
||||||
|
|
||||||
Validate.isTrue(config.contains("experience-table"), "You must specify an exp table");
|
Validate.isTrue(config.contains("experience-table"), "You must specify an exp table");
|
||||||
@ -180,10 +179,6 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The node identifier relative to its skill tree, like "extra_strength"
|
* @return The node identifier relative to its skill tree, like "extra_strength"
|
||||||
*/
|
*/
|
||||||
@ -237,7 +232,6 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
return NodeType.getNodeType(hasUpPathOrNode, hasRightPathOrNode, hasDownPathOrNode, hasLeftPathOrNode);
|
return NodeType.getNodeType(hasUpPathOrNode, hasRightPathOrNode, hasDownPathOrNode, hasLeftPathOrNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@ -255,7 +249,6 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
Placeholders holders = new Placeholders();
|
Placeholders holders = new Placeholders();
|
||||||
holders.register("name", getName());
|
holders.register("name", getName());
|
||||||
holders.register("node-state", playerData.getNodeStatus(this));
|
holders.register("node-state", playerData.getNodeStatus(this));
|
||||||
holders.register("size", getSize());
|
|
||||||
holders.register("level", playerData.getNodeLevel(this));
|
holders.register("level", playerData.getNodeLevel(this));
|
||||||
holders.register("max-level", getMaxLevel());
|
holders.register("max-level", getMaxLevel());
|
||||||
holders.register("max-children", getMaxChildren());
|
holders.register("max-children", getMaxChildren());
|
||||||
@ -263,15 +256,19 @@ public class SkillTreeNode implements ExperienceObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getLore(PlayerData playerData) {
|
public List<String> getLore(PlayerData playerData) {
|
||||||
Placeholders holders = getPlaceholders(playerData);
|
final int nodeLevel = playerData.getNodeLevel(this);
|
||||||
List<String> parsedLore = new ArrayList<>();
|
final List<String> parsedLore = new ArrayList<>();
|
||||||
if (!lores.containsKey(playerData.getNodeLevel(this)))
|
|
||||||
return parsedLore;
|
|
||||||
List<String> lore = lores.get(playerData.getNodeLevel(this));
|
|
||||||
lore.forEach(string -> parsedLore.add(
|
|
||||||
MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
|
|
||||||
return parsedLore;
|
|
||||||
|
|
||||||
|
for (int i = nodeLevel; i >= 0; i--) {
|
||||||
|
final List<String> found = lores.get(i);
|
||||||
|
if (found == null) continue;
|
||||||
|
|
||||||
|
final Placeholders holders = getPlaceholders(playerData);
|
||||||
|
found.forEach(string -> parsedLore.add(MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedLore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -8,7 +8,9 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.enchantment.EnchantItemEvent;
|
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
import org.bukkit.event.player.PlayerExpChangeEvent;
|
import org.bukkit.event.player.PlayerExpChangeEvent;
|
||||||
|
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||||
|
|
||||||
public class VanillaExperienceOverride implements Listener {
|
public class VanillaExperienceOverride implements Listener {
|
||||||
|
|
||||||
@ -16,10 +18,20 @@ public class VanillaExperienceOverride implements Listener {
|
|||||||
* When picking up exp orbs or any action like that
|
* When picking up exp orbs or any action like that
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void a(PlayerExpChangeEvent event) {
|
public void cancelChange(PlayerExpChangeEvent event) {
|
||||||
event.setAmount(0);
|
event.setAmount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void cancelDrop(PlayerDeathEvent event) {
|
||||||
|
event.setDroppedExp(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void cancelChange(PlayerRespawnEvent event) {
|
||||||
|
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> PlayerData.get(event.getPlayer()).refreshVanillaExp());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This event is not supported by the expChangeEvent. Since the event is
|
* This event is not supported by the expChangeEvent. Since the event is
|
||||||
* actually called before applying the enchant and consuming levels, we must
|
* actually called before applying the enchant and consuming levels, we must
|
||||||
@ -28,7 +40,7 @@ public class VanillaExperienceOverride implements Listener {
|
|||||||
* {@link EnchantItemEvent#setExpLevelCost(int)} does NOT work
|
* {@link EnchantItemEvent#setExpLevelCost(int)} does NOT work
|
||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void b(EnchantItemEvent event) {
|
public void cancelChange(EnchantItemEvent event) {
|
||||||
Player player = event.getEnchanter();
|
Player player = event.getEnchanter();
|
||||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> player.setLevel(PlayerData.get(player).getLevel()));
|
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> player.setLevel(PlayerData.get(player).getLevel()));
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
# The maximum level players can reach
|
# The maximum level players can reach
|
||||||
max-level: 100
|
max-level: 100
|
||||||
|
@ -26,15 +26,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
# Experience sources for main class experience.
|
# Experience sources for main class experience.
|
||||||
main-exp-sources:
|
main-exp-sources:
|
||||||
|
@ -42,15 +42,26 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore:
|
||||||
|
- ''
|
||||||
|
- '&a-50% Cooldown &7for Active Skills'
|
||||||
|
- '&a+30% Damage &7for Active Skills'
|
||||||
|
formula: "<ACTIVE>"
|
||||||
|
skill-buffs:
|
||||||
|
- 'skill_buff{modifier="cooldown";amount=-50;type="RELATIVE"}'
|
||||||
|
- 'skill_buff{modifier="damage";amount=30;type="RELATIVE"}'
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
# This is the default mana display options, however it is not mandatory
|
# This is the default mana display options, however it is not mandatory
|
||||||
# to have it in your class config file. Other classes do not have this
|
# to have it in your class config file. Other classes do not have this
|
||||||
@ -81,13 +92,13 @@ resource:
|
|||||||
|
|
||||||
# Scales with max mana.
|
# Scales with max mana.
|
||||||
type: MAX
|
type: MAX
|
||||||
|
|
||||||
# Regen from 3 to 10% of max mana every second
|
# Regen from 3 to 10% of max mana every second
|
||||||
value:
|
value:
|
||||||
base: 3
|
base: 3
|
||||||
per-level: .1
|
per-level: .1
|
||||||
max: 10
|
max: 10
|
||||||
|
|
||||||
# Only regen when out of combat.
|
# Only regen when out of combat.
|
||||||
off-combat: true
|
off-combat: true
|
||||||
|
|
||||||
@ -116,7 +127,7 @@ skills:
|
|||||||
FIRE_STORM:
|
FIRE_STORM:
|
||||||
level: 1
|
level: 1
|
||||||
max-level: 30
|
max-level: 30
|
||||||
|
|
||||||
# Specific skill modifiers based on class.
|
# Specific skill modifiers based on class.
|
||||||
# Arcane mage's fire storm may deal more damage
|
# Arcane mage's fire storm may deal more damage
|
||||||
# than an apprentice mage's fire storm.
|
# than an apprentice mage's fire storm.
|
||||||
|
@ -37,15 +37,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
skill-trees:
|
skill-trees:
|
||||||
- 'general'
|
- 'general'
|
||||||
|
@ -34,15 +34,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
skill-trees:
|
skill-trees:
|
||||||
- 'general'
|
- 'general'
|
||||||
|
@ -37,15 +37,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "&aSkill Slot I"
|
name: "&aSkill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "&aSkill Slot II"
|
name: "&aSkill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "&aSkill Slot III"
|
name: "&aSkill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "&aSkill Slot IV"
|
name: "&aSkill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
skill-trees:
|
skill-trees:
|
||||||
- 'general'
|
- 'general'
|
||||||
|
@ -40,15 +40,19 @@ skill-slots:
|
|||||||
1:
|
1:
|
||||||
name: "Skill Slot I"
|
name: "Skill Slot I"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
2:
|
2:
|
||||||
name: "Skill Slot II"
|
name: "Skill Slot II"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
3:
|
3:
|
||||||
name: "Skill Slot III"
|
name: "Skill Slot III"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
4:
|
4:
|
||||||
name: "Skill Slot IV"
|
name: "Skill Slot IV"
|
||||||
unlocked-by-default: true
|
unlocked-by-default: true
|
||||||
|
lore: []
|
||||||
|
|
||||||
skill-trees:
|
skill-trees:
|
||||||
- 'general'
|
- 'general'
|
||||||
|
@ -32,7 +32,7 @@ items:
|
|||||||
- ''
|
- ''
|
||||||
- '&8When Leveled Up:'
|
- '&8When Leveled Up:'
|
||||||
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
|
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
|
||||||
- '&7 +{buff_max_health} Max Health (&a+{total_max_health}&7)'
|
- '&7 +{buff_max_health}% Max Health (&a+{total_max_health}%&7)'
|
||||||
- ''
|
- ''
|
||||||
- '&eClick to level up for 1 attribute point.'
|
- '&eClick to level up for 1 attribute point.'
|
||||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||||
@ -50,7 +50,7 @@ items:
|
|||||||
- '&8When Leveled Up:'
|
- '&8When Leveled Up:'
|
||||||
- '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)'
|
- '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)'
|
||||||
- '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)'
|
- '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)'
|
||||||
- '&7 +{buff_attack_speed} Attack Speed (&a+{total_attack_speed}&7)'
|
- '&7 +{buff_attack_speed}% Attack Speed (&a+{total_attack_speed}%&7)'
|
||||||
- ''
|
- ''
|
||||||
- '&eClick to level up for 1 attribute point.'
|
- '&eClick to level up for 1 attribute point.'
|
||||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||||
|
@ -38,14 +38,11 @@ items:
|
|||||||
slots: [ 9,18,27 ]
|
slots: [ 9,18,27 ]
|
||||||
lore:
|
lore:
|
||||||
- ''
|
- ''
|
||||||
- '&aDescription:'
|
|
||||||
- '{tree-lore}'
|
- '{tree-lore}'
|
||||||
- ''
|
- ''
|
||||||
- '--------------------'
|
- '&e◆ Points: &6{max-point-spent}&e/&6{point-spent}'
|
||||||
- '&e◆Max points&e: &6{max-point-spent}'
|
- '&e◆ Current {name} &ePoints: &6{skill-tree-points}'
|
||||||
- '&e◆Points spent&e:&6 {point-spent}'
|
- '&e◆ Current Global Points: &6{global-points}'
|
||||||
- '&e◆Current {name} &epoints: &6{skill-tree-points}'
|
|
||||||
- '&e◆Current Global points: &6{global-points}'
|
|
||||||
|
|
||||||
next-tree-list-page:
|
next-tree-list-page:
|
||||||
function: 'next-tree-list-page'
|
function: 'next-tree-list-page'
|
||||||
@ -77,6 +74,7 @@ items:
|
|||||||
|
|
||||||
function: 'skill-tree-node'
|
function: 'skill-tree-node'
|
||||||
slots: [ 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,37,38,39,40,41,42,43,44 ]
|
slots: [ 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,37,38,39,40,41,42,43,44 ]
|
||||||
|
name: '&a{name}'
|
||||||
#The lore that will be displayed after the lore of the node.
|
#The lore that will be displayed after the lore of the node.
|
||||||
#The {node-lore} placeholder will be replaced by the lore specified in the skill tree node config.
|
#The {node-lore} placeholder will be replaced by the lore specified in the skill tree node config.
|
||||||
#All the placeholders you see here can also be used in the node lore.
|
#All the placeholders you see here can also be used in the node lore.
|
||||||
@ -86,24 +84,23 @@ items:
|
|||||||
- '&7Current Level: &6{current-level}'
|
- '&7Current Level: &6{current-level}'
|
||||||
- '&7Max Level: &6{max-level}'
|
- '&7Max Level: &6{max-level}'
|
||||||
- '&7Max Children: &6{max-children}'
|
- '&7Max Children: &6{max-children}'
|
||||||
- '&7Points required: &6{point-consumed}'
|
- '&7Points Required: &6{point-consumed}'
|
||||||
- '&7Size: &6{size}'
|
- '&7Size: &6{size}'
|
||||||
- '--------------------'
|
- ''
|
||||||
- '&7⧆ &6Requirements: '
|
- '&7⧆ &6Requirements: '
|
||||||
- '&fStrong Parents: '
|
- '&fStrong Parents: '
|
||||||
- '{strong-parents}'
|
- '{strong-parents}'
|
||||||
- ''
|
- ''
|
||||||
- '&fSoft Parents: '
|
- '&fSoft Parents: '
|
||||||
- '{soft-parents}'
|
- '{soft-parents}'
|
||||||
- '--------------------'
|
|
||||||
- '{node-lore}'
|
|
||||||
- '--------------------'
|
|
||||||
- '&e◆Max points for {skill-tree}&e: &6{max-point-spent}'
|
|
||||||
- '&e◆Points spent for {skill-tree}&e:&6 {point-spent}'
|
|
||||||
- '&e◆Current {skill-tree} &epoints: &6{skill-tree-points}'
|
|
||||||
- '&e◆Current &6global&e points: &6{global-points}'
|
|
||||||
path-lore:
|
|
||||||
- ''
|
- ''
|
||||||
|
- '{node-lore}'
|
||||||
|
- ''
|
||||||
|
- '&e◆ Max points for {skill-tree}&e: &6{max-point-spent}'
|
||||||
|
- '&e◆ Points spent for {skill-tree}&e:&6 {point-spent}'
|
||||||
|
- '&e◆ Current {skill-tree} &ePoints: &6{skill-tree-points}'
|
||||||
|
- '&e◆ Current &6global&e points: &6{global-points}'
|
||||||
|
path-lore: []
|
||||||
|
|
||||||
#This is the name that will be displayed for each status.
|
#This is the name that will be displayed for each status.
|
||||||
status-names:
|
status-names:
|
||||||
|
@ -50,6 +50,7 @@ items:
|
|||||||
|
|
||||||
function: 'skill-tree-node'
|
function: 'skill-tree-node'
|
||||||
slots: [ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44 ]
|
slots: [ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44 ]
|
||||||
|
name: '&a{name}'
|
||||||
#The lore that will be displayed after the lore of the node.
|
#The lore that will be displayed after the lore of the node.
|
||||||
#The {node-lore} placeholder will be replaced by the lore specified in the skill tree node config.
|
#The {node-lore} placeholder will be replaced by the lore specified in the skill tree node config.
|
||||||
#All the placeholders you see here can also be used in the node lore.
|
#All the placeholders you see here can also be used in the node lore.
|
||||||
@ -61,22 +62,21 @@ items:
|
|||||||
- '&7Max Children: &6{max-children}'
|
- '&7Max Children: &6{max-children}'
|
||||||
- '&7Points required: &6{point-consumed}'
|
- '&7Points required: &6{point-consumed}'
|
||||||
- '&7Size: &6{size}'
|
- '&7Size: &6{size}'
|
||||||
- '--------------------'
|
- ''
|
||||||
- '&7⧆ &6Requirements: '
|
- '&7⧆ &6Requirements: '
|
||||||
- '&fStrong Parents: '
|
- '&fStrong Parents: '
|
||||||
- '{strong-parents}'
|
- '{strong-parents}'
|
||||||
- ''
|
- ''
|
||||||
- '&fSoft Parents: '
|
- '&fSoft Parents: '
|
||||||
- '{soft-parents}'
|
- '{soft-parents}'
|
||||||
- '--------------------'
|
|
||||||
- '{node-lore}'
|
|
||||||
- '--------------------'
|
|
||||||
- '&e◆Max points for {skill-tree}&e: &6{max-point-spent}'
|
|
||||||
- '&e◆Points spent for {skill-tree}&e:&6 {point-spent}'
|
|
||||||
- '&e◆Current {skill-tree} &epoints: &6{skill-tree-points}'
|
|
||||||
- '&e◆Current &6global&e points: &6{global-points}'
|
|
||||||
path-lore:
|
|
||||||
- ''
|
- ''
|
||||||
|
- '{node-lore}'
|
||||||
|
- ''
|
||||||
|
- '&e◆ Max points for {skill-tree}&e: &6{max-point-spent}'
|
||||||
|
- '&e◆ Points spent for {skill-tree}&e:&6 {point-spent}'
|
||||||
|
- '&e◆ Current {skill-tree} &epoints: &6{skill-tree-points}'
|
||||||
|
- '&e◆ Current &6global&e points: &6{global-points}'
|
||||||
|
path-lore: []
|
||||||
|
|
||||||
#This is the name that will be displayed for each status.
|
#This is the name that will be displayed for each status.
|
||||||
status-names:
|
status-names:
|
||||||
|
Loading…
Reference in New Issue
Block a user