More cleaning up

This commit is contained in:
Jules 2023-04-10 16:12:57 +02:00
parent b694cf8cf4
commit 9b2c972ca4
23 changed files with 640 additions and 672 deletions

View File

@ -88,6 +88,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints; private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints;
private double experience; private double experience;
private double mana, stamina, stellium; 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. * Health is stored in playerData because when saving the playerData we can't access the player health anymore as the payer is Offline.
*/ */
@ -97,6 +98,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private final PlayerQuests questData; private final PlayerQuests questData;
private final PlayerStats playerStats; private final PlayerStats playerStats;
private final List<UUID> friends = new ArrayList<>(); private final List<UUID> friends = new ArrayList<>();
/**
* @deprecated Use {@link #hasUnlocked(Unlockable)} instead
*/
@Deprecated
private final Set<String> waypoints = new HashSet<>(); private final Set<String> waypoints = new HashSet<>();
private final Map<String, Integer> skills = new HashMap<>(); private final Map<String, Integer> skills = new HashMap<>();
private final Map<Integer, BoundSkillInfo> boundSkills = new HashMap<>(); private final Map<Integer, BoundSkillInfo> boundSkills = new HashMap<>();
@ -147,11 +153,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
this.mmoData = mmoData; this.mmoData = mmoData;
questData = new PlayerQuests(this); questData = new PlayerQuests(this);
playerStats = new PlayerStats(this); playerStats = new PlayerStats(this);
} }
/** /**
* Update all references after /mmocore reload so there can be garbage * Update all references after /mmocore reload so there can be garbage
* collection with old plugin objects like class or skill instances. * collection with old plugin objects like class or skill instances.
@ -171,18 +174,16 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
Iterator<Integer> ite = boundSkills.keySet().iterator(); Iterator<Integer> ite = boundSkills.keySet().iterator();
while (ite.hasNext()) while (ite.hasNext()) try {
try { int slot = ite.next();
int slot = ite.next(); BoundSkillInfo boundSkillInfo = new BoundSkillInfo(boundSkills.get(slot));
BoundSkillInfo boundSkillInfo = new BoundSkillInfo(boundSkills.get(slot)); boundSkills.put(slot, boundSkillInfo);
boundSkills.put(slot, boundSkillInfo); } catch (Exception ignored) {
} catch (Exception ignored) { }
}
for (SkillTree skillTree : getProfess().getSkillTrees()) for (SkillTree skillTree : getProfess().getSkillTrees())
for (SkillTreeNode node : skillTree.getNodes()) for (SkillTreeNode node : skillTree.getNodes())
if (!nodeLevels.containsKey(node)) if (!nodeLevels.containsKey(node)) nodeLevels.put(node, 0);
nodeLevels.put(node, 0);
setupSkillTree(); setupSkillTree();
} }
@ -237,9 +238,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void clearNodeTimesClaimed() { public void clearNodeTimesClaimed() {
final Iterator<String> ite = tableItemClaims.keySet().iterator(); final Iterator<String> ite = tableItemClaims.keySet().iterator();
while (ite.hasNext()) while (ite.hasNext()) if (ite.next().startsWith(SkillTreeNode.KEY_PREFIX)) ite.remove();
if (ite.next().startsWith(SkillTreeNode.KEY_PREFIX))
ite.remove();
} }
public Set<Map.Entry<String, Integer>> getNodeLevelsEntrySet() { public Set<Map.Entry<String, Integer>> getNodeLevelsEntrySet() {
@ -254,8 +253,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
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)) if (modifier.getKey().startsWith(StatTrigger.TRIGGER_PREFIX)) iter.remove();
iter.remove();
} }
} }
} }
@ -272,8 +270,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public boolean canIncrementNodeLevel(SkillTreeNode node) { public boolean canIncrementNodeLevel(SkillTreeNode node) {
NodeStatus nodeStatus = nodeStates.get(node); NodeStatus nodeStatus = nodeStates.get(node);
//Check the State of the node //Check the State of the node
if (nodeStatus != NodeStatus.UNLOCKED && nodeStatus != NodeStatus.UNLOCKABLE) if (nodeStatus != NodeStatus.UNLOCKED && nodeStatus != NodeStatus.UNLOCKABLE) return false;
return false;
return getNodeLevel(node) < node.getMaxLevel() && (skillTreePoints.getOrDefault(node.getTree().getId(), 0) + skillTreePoints.getOrDefault("global", 0) >= node.getSkillTreePointsConsumed()); return getNodeLevel(node) < node.getMaxLevel() && (skillTreePoints.getOrDefault(node.getTree().getId(), 0) + skillTreePoints.getOrDefault("global", 0) >= node.getSkillTreePointsConsumed());
} }
@ -284,20 +281,18 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*/ */
public void incrementNodeLevel(SkillTreeNode node) { public void incrementNodeLevel(SkillTreeNode node) {
setNodeLevel(node, getNodeLevel(node) + 1); setNodeLevel(node, getNodeLevel(node) + 1);
//Claims the nodes experience table. // Claims the nodes experience table.
node.getExperienceTable().claim(this, getNodeLevel(node), node); node.getExperienceTable().claim(this, getNodeLevel(node), node);
if (nodeStates.get(node) == NodeStatus.UNLOCKABLE) if (nodeStates.get(node) == NodeStatus.UNLOCKABLE) setNodeState(node, NodeStatus.UNLOCKED);
setNodeState(node, NodeStatus.UNLOCKED);
int pointToWithdraw = node.getSkillTreePointsConsumed(); int pointToWithdraw = node.getSkillTreePointsConsumed();
if (skillTreePoints.get(node.getTree().getId()) > 0) { if (skillTreePoints.get(node.getTree().getId()) > 0) {
int pointWithdrawn = Math.min(pointToWithdraw, skillTreePoints.get(node.getTree().getId())); int pointWithdrawn = Math.min(pointToWithdraw, skillTreePoints.get(node.getTree().getId()));
withdrawSkillTreePoints(node.getTree().getId(), pointWithdrawn); withdrawSkillTreePoints(node.getTree().getId(), pointWithdrawn);
pointToWithdraw -= pointWithdrawn; pointToWithdraw -= pointWithdrawn;
} }
if (pointToWithdraw > 0) if (pointToWithdraw > 0) withdrawSkillTreePoints("global", pointToWithdraw);
withdrawSkillTreePoints("global", pointToWithdraw); // We unload the nodeStates map (for the skill tree) and reload it completely
//We unload the nodeStates map (for the skill tree) and reload it completely
for (SkillTreeNode node1 : node.getTree().getNodes()) for (SkillTreeNode node1 : node.getTree().getNodes())
nodeStates.remove(node1); nodeStates.remove(node1);
node.getTree().setupNodeStates(this); node.getTree().setupNodeStates(this);
@ -321,8 +316,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize()); DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize());
return skillTree.getIcon(displayInfo); return skillTree.getIcon(displayInfo);
} }
if (skillTree.isPath(coordinates)) if (skillTree.isPath(coordinates)) return skillTree.getIcon(DisplayInfo.pathInfo);
return skillTree.getIcon(DisplayInfo.pathInfo);
return null; return null;
} }
@ -377,8 +371,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public Map<String, Integer> getNodeTimesClaimed() { public Map<String, Integer> getNodeTimesClaimed() {
Map<String, Integer> result = new HashMap<>(); Map<String, Integer> result = new HashMap<>();
tableItemClaims.forEach((str, val) -> { tableItemClaims.forEach((str, val) -> {
if (str.startsWith(SkillTreeNode.KEY_PREFIX)) if (str.startsWith(SkillTreeNode.KEY_PREFIX)) result.put(str, val);
result.put(str, val);
}); });
return result; return result;
} }
@ -386,19 +379,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
/** /**
* @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.
* <p>
* Looks at the real value and thus remove the plugin identifier
*/ */
public boolean hasUnlocked(Unlockable unlockable) { public boolean hasUnlocked(Unlockable unlockable) {
return hasUnlocked(unlockable.getUnlockNamespacedKey()); return unlockable.isUnlockedByDefault() || unlockedItems.contains(unlockable.getUnlockNamespacedKey());
}
public boolean hasUnlocked(String unlockNamespacedKey) {
return unlockedItems
.stream()
.filter(key -> key.equals(unlockNamespacedKey))
.collect(Collectors.toList()).size() != 0;
} }
/** /**
@ -407,6 +390,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* @return If the item was locked when calling this method. * @return If the item was locked when calling this method.
*/ */
public boolean unlock(Unlockable unlockable) { public boolean unlock(Unlockable unlockable) {
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot unlock an item unlocked by default");
final boolean wasLocked = unlockedItems.add(unlockable.getUnlockNamespacedKey()); final boolean wasLocked = unlockedItems.add(unlockable.getUnlockNamespacedKey());
// Call the event synchronously // Call the event synchronously
if (wasLocked) if (wasLocked)
@ -421,6 +405,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* @return If the item was unlocked when calling this method. * @return If the item was unlocked when calling this method.
*/ */
public boolean lock(Unlockable unlockable) { public boolean lock(Unlockable unlockable) {
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot lock an item unlocked by default");
boolean wasUnlocked = unlockedItems.remove(unlockable.getUnlockNamespacedKey()); boolean wasUnlocked = unlockedItems.remove(unlockable.getUnlockNamespacedKey());
if (wasUnlocked) if (wasUnlocked)
//Calls the event synchronously //Calls the event synchronously
@ -449,8 +434,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Remove from party if it is MMO Party Module // Remove from party if it is MMO Party Module
if (MMOCore.plugin.partyModule instanceof MMOCorePartyModule) { if (MMOCore.plugin.partyModule instanceof MMOCorePartyModule) {
AbstractParty party = getParty(); AbstractParty party = getParty();
if (party != null && party instanceof Party) if (party != null && party instanceof Party) ((Party) party).removeMember(this);
((Party) party).removeMember(this);
} }
// Close combat handler // Close combat handler
@ -460,8 +444,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
questData.close(); questData.close();
// Stop skill casting // Stop skill casting
if (isCasting()) if (isCasting()) leaveSkillCasting();
leaveSkillCasting();
} }
public MMOPlayerData getMMOPlayerData() { public MMOPlayerData getMMOPlayerData() {
@ -536,12 +519,12 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
skillReallocationPoints += value; skillReallocationPoints += value;
} }
public int countSkillPointsWhenReallocate() { public int countSkillPointsSpent() {
int sum = 0; int sum = 0;
for (ClassSkill skill : getProfess().getSkills()) { for (ClassSkill skill : getProfess().getSkills())
//0 if the skill is level 1(just unlocked) or 0 locked. // 0 if the skill is level 1 (just unlocked) or 0 locked
sum += Math.max(0, getSkillLevel(skill.getSkill()) - 1); sum += Math.max(0, getSkillLevel(skill.getSkill()) - 1);
}
return sum; return sum;
} }
@ -612,16 +595,14 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveLevels(int value, EXPSource source) { public void giveLevels(int value, EXPSource source) {
int total = 0; int total = 0;
while (value-- > 0) while (value-- > 0) total += getProfess().getExpCurve().getExperience(getLevel() + value + 1);
total += getProfess().getExpCurve().getExperience(getLevel() + value + 1);
giveExperience(total, source); giveExperience(total, source);
} }
public void setExperience(double value) { public void setExperience(double value) {
experience = Math.max(0, value); experience = Math.max(0, value);
if (isOnline()) if (isOnline()) refreshVanillaExp();
refreshVanillaExp();
} }
/** /**
@ -629,8 +610,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* This updates the exp bar to display the player class level and exp. * This updates the exp bar to display the player class level and exp.
*/ */
public void refreshVanillaExp() { public void refreshVanillaExp() {
if (!MMOCore.plugin.configManager.overrideVanillaExp) if (!MMOCore.plugin.configManager.overrideVanillaExp) return;
return;
getPlayer().sendExperienceChange(0.01f); getPlayer().sendExperienceChange(0.01f);
getPlayer().setLevel(getLevel()); getPlayer().setLevel(getLevel());
@ -716,19 +696,16 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
public void heal(double heal, PlayerResourceUpdateEvent.UpdateReason reason) { public void heal(double heal, PlayerResourceUpdateEvent.UpdateReason reason) {
if (!isOnline()) if (!isOnline()) return;
return;
// Avoid calling an useless event // Avoid calling an useless event
double max = getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); double max = getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double newest = Math.max(0, Math.min(getPlayer().getHealth() + heal, max)); double newest = Math.max(0, Math.min(getPlayer().getHealth() + heal, max));
if (getPlayer().getHealth() == newest) if (getPlayer().getHealth() == newest) return;
return;
PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.HEALTH, heal, reason); PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.HEALTH, heal, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled()) return;
return;
// Use updated amount from event // Use updated amount from event
getPlayer().setHealth(Math.max(0, Math.min(getPlayer().getHealth() + event.getAmount(), max))); getPlayer().setHealth(Math.max(0, Math.min(getPlayer().getHealth() + event.getAmount(), max)));
@ -757,13 +734,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
public void sendFriendRequest(PlayerData target) { public void sendFriendRequest(PlayerData target) {
if (!isOnline() || !target.isOnline()) if (!isOnline() || !target.isOnline()) return;
return;
setLastActivity(PlayerActivity.FRIEND_REQUEST); setLastActivity(PlayerActivity.FRIEND_REQUEST);
FriendRequest request = new FriendRequest(this, target); FriendRequest request = new FriendRequest(this, target);
new ConfigMessage("friend-request").addPlaceholders("player", getPlayer().getName(), "uuid", request.getUniqueId().toString()) new ConfigMessage("friend-request").addPlaceholders("player", getPlayer().getName(), "uuid", request.getUniqueId().toString()).sendAsJSon(target.getPlayer());
.sendAsJSon(target.getPlayer());
MMOCore.plugin.requestManager.registerRequest(request); MMOCore.plugin.requestManager.registerRequest(request);
} }
@ -791,9 +766,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
int t; int t;
public void run() { public void run() {
if (!isOnline() || getPlayer().getLocation().getBlockX() != x if (!isOnline() || getPlayer().getLocation().getBlockX() != x || getPlayer().getLocation().getBlockY() != y || getPlayer().getLocation().getBlockZ() != z) {
|| getPlayer().getLocation().getBlockY() != y
|| getPlayer().getLocation().getBlockZ() != z) {
MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_CANCELLED).playTo(getPlayer()); MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_CANCELLED).playTo(getPlayer());
MMOCore.plugin.configManager.getSimpleMessage("warping-canceled").send(getPlayer()); MMOCore.plugin.configManager.getSimpleMessage("warping-canceled").send(getPlayer());
giveStellium(cost, PlayerResourceUpdateEvent.UpdateReason.USE_WAYPOINT); giveStellium(cost, PlayerResourceUpdateEvent.UpdateReason.USE_WAYPOINT);
@ -813,11 +786,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_CHARGE).playTo(getPlayer(), 1, (float) (.5 + t * 1.5 / warpTime)); MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_CHARGE).playTo(getPlayer(), 1, (float) (.5 + t * 1.5 / warpTime));
final double r = Math.sin((double) t / warpTime * Math.PI); final double r = Math.sin((double) t / warpTime * Math.PI);
for (double j = 0; j < Math.PI * 2; j += Math.PI / 4) for (double j = 0; j < Math.PI * 2; j += Math.PI / 4)
getPlayer().getLocation().getWorld().spawnParticle(Particle.REDSTONE, getPlayer().getLocation().add( 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), 1, new Particle.DustOptions(Color.PURPLE, 1.25f));
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); }.runTaskTimer(MMOCore.plugin, 0, 1);
} }
@ -854,14 +823,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Splitting exp through party members // Splitting exp through party members
final AbstractParty party; final AbstractParty party;
if (splitExp && (party = getParty()) != null && MMOCore.plugin.configManager.splitMainExp) { if (splitExp && (party = getParty()) != null && MMOCore.plugin.configManager.splitMainExp) {
final List<PlayerData> nearbyMembers = party.getOnlineMembers().stream() final List<PlayerData> nearbyMembers = party.getOnlineMembers().stream().filter(pd -> {
.filter(pd -> { if (equals(pd) || pd.hasReachedMaxLevel() || Math.abs(pd.getLevel() - getLevel()) > MMOCore.plugin.configManager.maxPartyLevelDifference)
if (equals(pd) || pd.hasReachedMaxLevel() || Math.abs(pd.getLevel() - getLevel()) > MMOCore.plugin.configManager.maxPartyLevelDifference) return false;
return false;
final double maxDis = MMOCore.plugin.configManager.partyMaxExpSplitRange; final double maxDis = MMOCore.plugin.configManager.partyMaxExpSplitRange;
return maxDis <= 0 || (pd.getPlayer().getWorld().equals(getPlayer().getWorld()) && pd.getPlayer().getLocation().distanceSquared(getPlayer().getLocation()) < maxDis * maxDis); return maxDis <= 0 || (pd.getPlayer().getWorld().equals(getPlayer().getWorld()) && pd.getPlayer().getLocation().distanceSquared(getPlayer().getLocation()) < maxDis * maxDis);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
value /= (nearbyMembers.size() + 1); value /= (nearbyMembers.size() + 1);
for (PlayerData member : nearbyMembers) for (PlayerData member : nearbyMembers)
member.giveExperience(value, source, null, false); member.giveExperience(value, source, null, false);
@ -878,8 +846,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source); PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled()) return;
return;
// Experience hologram // Experience hologram
if (hologramLocation != null && isOnline()) if (hologramLocation != null && isOnline())
@ -900,8 +867,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
level = getLevel() + 1; level = getLevel() + 1;
// Apply class experience table // Apply class experience table
if (getProfess().hasExperienceTable()) if (getProfess().hasExperienceTable()) getProfess().getExperienceTable().claim(this, level, getProfess());
getProfess().getExperienceTable().claim(this, level, getProfess());
} }
if (level > oldLevel) { if (level > oldLevel) {
@ -940,13 +906,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat("MAX_MANA"); double max = getStats().getStat("MAX_MANA");
double newest = Math.max(0, Math.min(mana + amount, max)); double newest = Math.max(0, Math.min(mana + amount, max));
if (mana == newest) if (mana == newest) return;
return;
PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.MANA, amount, reason); PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.MANA, amount, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled()) return;
return;
// Use updated amount from Bukkit event // Use updated amount from Bukkit event
mana = Math.max(0, Math.min(mana + event.getAmount(), max)); mana = Math.max(0, Math.min(mana + event.getAmount(), max));
@ -965,13 +929,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat("MAX_STAMINA"); double max = getStats().getStat("MAX_STAMINA");
double newest = Math.max(0, Math.min(stamina + amount, max)); double newest = Math.max(0, Math.min(stamina + amount, max));
if (stamina == newest) if (stamina == newest) return;
return;
PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.STAMINA, amount, reason); PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.STAMINA, amount, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled()) return;
return;
// Use updated amount from Bukkit event // Use updated amount from Bukkit event
stamina = Math.max(0, Math.min(stamina + event.getAmount(), max)); stamina = Math.max(0, Math.min(stamina + event.getAmount(), max));
@ -990,13 +952,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Avoid calling useless event // Avoid calling useless event
double max = getStats().getStat("MAX_STELLIUM"); double max = getStats().getStat("MAX_STELLIUM");
double newest = Math.max(0, Math.min(stellium + amount, max)); double newest = Math.max(0, Math.min(stellium + amount, max));
if (stellium == newest) if (stellium == newest) return;
return;
PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.STELLIUM, amount, reason); PlayerResourceUpdateEvent event = new PlayerResourceUpdateEvent(this, PlayerResource.STELLIUM, amount, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled()) return;
return;
// Use updated amount from Bukkit event // Use updated amount from Bukkit event
stellium = Math.max(0, Math.min(stellium + event.getAmount(), max)); stellium = Math.max(0, Math.min(stellium + event.getAmount(), max));
@ -1113,10 +1073,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} }
public void refreshBoundedSkill(String skill) { public void refreshBoundedSkill(String skill) {
boundSkills.values() boundSkills.values().stream().filter(skillInfo -> skillInfo.getClassSkill().getSkill().getHandler().getId().equals(skill)).forEach(BoundSkillInfo::refresh);
.stream()
.filter(skillInfo -> skillInfo.getClassSkill().getSkill().getHandler().getId().equals(skill))
.forEach(BoundSkillInfo::refresh);
} }
@Deprecated @Deprecated
@ -1175,34 +1132,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Clear old skills // Clear old skills
for (Iterator<BoundSkillInfo> iterator = boundSkills.values().iterator(); iterator.hasNext(); ) for (Iterator<BoundSkillInfo> iterator = boundSkills.values().iterator(); iterator.hasNext(); )
if (!getProfess().hasSkill(iterator.next().getClassSkill().getSkill())) if (!getProfess().hasSkill(iterator.next().getClassSkill().getSkill())) iterator.remove();
iterator.remove();
// Update stats // Update stats
if (isOnline()) if (isOnline()) getStats().updateStats();
getStats().updateStats();
if (profess != null) {
// Loads the classUnlockedSkills
profess.getSkills()
.stream()
.filter(ClassSkill::isUnlockedByDefault)
.forEach(skill -> unlock(skill.getSkill()));
// Loads the classUnlockedSkills
profess.getSkills()
.stream()
.filter(ClassSkill::isUnlockedByDefault)
.forEach(skill -> unlock(skill.getSkill()));
// Loads the classUnlockedSlots
profess.getSlots()
.stream()
.filter(SkillSlot::isUnlockedByDefault)
.forEach(this::unlock);
}
} }
public boolean hasSkillBound(int slot) { public boolean hasSkillBound(int slot) {
@ -1213,7 +1146,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return boundSkills.containsKey(slot) ? boundSkills.get(slot).getClassSkill() : null; return boundSkills.containsKey(slot) ? boundSkills.get(slot).getClassSkill() : null;
} }
@Deprecated @Deprecated
public void setBoundSkill(int slot, ClassSkill skill) { public void setBoundSkill(int slot, ClassSkill skill) {
bindSkill(slot, skill); bindSkill(slot, skill);
@ -1230,8 +1162,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
Validate.notNull(skill, "Skill cannot be null"); Validate.notNull(skill, "Skill cannot be null");
//Unbinds the previous skill (Important for passive skills. //Unbinds the previous skill (Important for passive skills.
String skillId = skill.getSkill().getHandler().getId(); String skillId = skill.getSkill().getHandler().getId();
if (boundSkills.containsKey(slot)) if (boundSkills.containsKey(slot)) boundSkills.get(slot).unbind();
boundSkills.get(slot).unbind();
if (slot >= 0) { if (slot >= 0) {
//We apply the skill buffs associated with the slot to the skill. //We apply the skill buffs associated with the slot to the skill.
for (SkillModifierTrigger skillBuffTrigger : profess.getSkillSlot(slot).getSkillBuffTriggers()) for (SkillModifierTrigger skillBuffTrigger : profess.getSkillSlot(slot).getSkillBuffTriggers())
@ -1251,8 +1182,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void unbindSkill(int slot) { public void unbindSkill(int slot) {
// We remove the skill buffs associated with the slot from the skill that is . // We remove the skill buffs associated with the slot from the skill that is .
profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger -> profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(this, boundSkills.get(slot).getClassSkill().getSkill().getHandler()));
skillBuffTrigger.remove(this, boundSkills.get(slot).getClassSkill().getSkill().getHandler()));
BoundSkillInfo boundSkillInfo = boundSkills.remove(slot); BoundSkillInfo boundSkillInfo = boundSkills.remove(slot);
boundSkillInfo.unbind(); boundSkillInfo.unbind();
@ -1282,8 +1212,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
@Deprecated @Deprecated
public boolean canChooseSubclass() { public boolean canChooseSubclass() {
for (Subclass subclass : getProfess().getSubclasses()) for (Subclass subclass : getProfess().getSubclasses())
if (getLevel() >= subclass.getLevel()) if (getLevel() >= subclass.getLevel()) return true;
return true;
return false; return false;
} }

View File

@ -35,7 +35,6 @@ import net.Indyuce.mmocore.skill.cast.ComboMap;
import net.Indyuce.mmocore.experience.ExperienceObject; import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.skilltree.tree.SkillTree; import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
@ -185,8 +184,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
} }
// Skill slots // Skill slots
Validate.isTrue(config.isConfigurationSection("skill-slots"), "You must define the skills-slots for class " + id); for (int i = 1; i < MMOCore.plugin.configManager.maxSkillSlots + 1; i++) {
for (int i = 1; i < MMOCore.plugin.configManager.maxSlots + 1; i++) {
if (config.contains("skill-slots." + i)) if (config.contains("skill-slots." + i))
skillSlots.put(i, new SkillSlot(config.getConfigurationSection("skill-slots." + i))); skillSlots.put(i, new SkillSlot(config.getConfigurationSection("skill-slots." + i)));
else else
@ -448,6 +446,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return skillSlots.values(); return skillSlots.values();
} }
@NotNull
public ClassSkill getSkill(RegisteredSkill skill) { public ClassSkill getSkill(RegisteredSkill skill) {
return getSkill(skill.getHandler().getId()); return getSkill(skill.getHandler().getId());
} }

View File

@ -4,8 +4,10 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
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.quest.trigger.api.Removable; import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
public class UnlockSkillTrigger extends Trigger implements Removable { public class UnlockSkillTrigger extends Trigger implements Removable {
@ -13,17 +15,22 @@ public class UnlockSkillTrigger extends Trigger implements Removable {
public UnlockSkillTrigger(MMOLineConfig config) { public UnlockSkillTrigger(MMOLineConfig config) {
super(config); super(config);
config.validateKeys("skill"); config.validateKeys("skill");
skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(config.getString("skill"))); skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(config.getString("skill")));
} }
@Override @Override
public void apply(PlayerData player) { public void apply(PlayerData playerData) {
player.unlock(skill); final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null)
playerData.unlock(found);
} }
@Override @Override
public void remove(PlayerData playerData) { public void remove(PlayerData playerData) {
playerData.lock(skill); final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null)
playerData.lock(found);
} }
} }

View File

@ -15,19 +15,19 @@ public class UnlockSlotTrigger extends Trigger implements Removable {
super(config); super(config);
config.validateKeys("slot"); config.validateKeys("slot");
slot = Integer.parseInt("slot"); slot = Integer.parseInt("slot");
Validate.isTrue(slot > 0 && slot <= MMOCore.plugin.configManager.maxSlots, "The slot should be between 1 and " + MMOCore.plugin.configManager.maxSlots); Validate.isTrue(slot > 0 && slot <= MMOCore.plugin.configManager.maxSkillSlots, "The slot should be between 1 and " + MMOCore.plugin.configManager.maxSkillSlots);
} }
@Override @Override
public void apply(PlayerData player) { public void apply(PlayerData player) {
SkillSlot skillSlot = player.getProfess().getSkillSlot(slot); final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
if (!player.hasUnlocked(skillSlot)) if (!player.hasUnlocked(skillSlot))
player.unlock(skillSlot); player.unlock(skillSlot);
} }
@Override @Override
public void remove(PlayerData player) { public void remove(PlayerData player) {
SkillSlot skillSlot = player.getProfess().getSkillSlot(slot); final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
if (player.hasUnlocked(skillSlot)) if (player.hasUnlocked(skillSlot))
player.lock(skillSlot); player.lock(skillSlot);
} }

View File

@ -112,18 +112,18 @@ public class SkillCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
if (lock) { if (lock) {
if (!playerData.hasUnlocked(skill.getSkill())) { if (!playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already locked" + " for " + player.getName()); CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already locked" + " for " + player.getName());
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
playerData.lock(skill.getSkill()); playerData.lock(skill);
} else { } else {
if (playerData.hasUnlocked(skill.getSkill())) { if (playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already unlocked" + " for " + player.getName()); CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already unlocked" + " for " + player.getName());
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
playerData.unlock(skill.getSkill()); playerData.unlock(skill);
} }
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill.getSkill().getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName())); CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill.getSkill().getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
return CommandResult.SUCCESS; return CommandResult.SUCCESS;

View File

@ -58,7 +58,7 @@ public class SkillList extends EditableInventory {
Placeholders holders = new Placeholders(); Placeholders holders = new Placeholders();
holders.register("skill_points", inv.getPlayerData().getSkillPoints()); holders.register("skill_points", inv.getPlayerData().getSkillPoints());
holders.register("points", inv.getPlayerData().getSkillReallocationPoints()); holders.register("points", inv.getPlayerData().getSkillReallocationPoints());
holders.register("total", inv.getPlayerData().countSkillPointsWhenReallocate()); holders.register("total", inv.getPlayerData().countSkillPointsSpent());
return holders; return holders;
} }
}; };
@ -75,6 +75,7 @@ public class SkillList extends EditableInventory {
return inv.page > 0; return inv.page > 0;
} }
}; };
if (function.equals("next")) { if (function.equals("next")) {
return new SimplePlaceholderItem<SkillViewerInventory>(config) { return new SimplePlaceholderItem<SkillViewerInventory>(config) {
@ -159,10 +160,10 @@ public class SkillList extends EditableInventory {
@Override @Override
public ItemStack display(SkillViewerInventory inv, int n) { public ItemStack display(SkillViewerInventory inv, int n) {
if (!inv.getPlayerData().hasUnlocked("slot:" + (n+1))) { final SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1);
if (!inv.getPlayerData().hasUnlocked(skillSlot))
return new ItemStack(Material.AIR); return new ItemStack(Material.AIR);
}
SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1);
ItemStack item = super.display(inv, n); ItemStack item = super.display(inv, n);
if (!inv.getPlayerData().hasSkillBound(n + 1)) { if (!inv.getPlayerData().hasSkillBound(n + 1)) {
//If there is an item filled in the slot config it shows it, else shows the default item. //If there is an item filled in the slot config it shows it, else shows the default item.
@ -180,7 +181,6 @@ public class SkillList extends EditableInventory {
meta.setCustomModelData(customModelData); meta.setCustomModelData(customModelData);
} }
item.setItemMeta(meta); item.setItemMeta(meta);
} }
return item; return item;
@ -209,8 +209,6 @@ public class SkillList extends EditableInventory {
} }
} }
;
public class SkillItem extends InventoryItem<SkillViewerInventory> { public class SkillItem extends InventoryItem<SkillViewerInventory> {
public SkillItem(ConfigurationSection config) { public SkillItem(ConfigurationSection config) {
super(Material.BARRIER, config); super(Material.BARRIER, config);
@ -284,7 +282,6 @@ public class SkillList extends EditableInventory {
shiftCost = 1; shiftCost = 1;
} }
} }
} }
@Override @Override
@ -315,7 +312,7 @@ public class SkillList extends EditableInventory {
super(playerData, editable); super(playerData, editable);
skills = playerData.getProfess().getSkills() skills = playerData.getProfess().getSkills()
.stream() .stream()
.filter((classSkill) -> playerData.hasUnlocked(classSkill.getSkill())) .filter((classSkill) -> playerData.hasUnlocked(classSkill))
.sorted(Comparator.comparingInt(ClassSkill::getUnlockLevel)) .sorted(Comparator.comparingInt(ClassSkill::getUnlockLevel))
.collect(Collectors.toList()); .collect(Collectors.toList());
skillSlots = getEditable().getByFunction("skill").getSlots(); skillSlots = getEditable().getByFunction("skill").getSlots();
@ -347,7 +344,7 @@ public class SkillList extends EditableInventory {
} }
if (item.getFunction().equals("reallocation")) { if (item.getFunction().equals("reallocation")) {
int spent = getPlayerData().countSkillPointsWhenReallocate(); int spent = getPlayerData().countSkillPointsSpent();
if (spent < 1) { if (spent < 1) {
MMOCore.plugin.configManager.getSimpleMessage("no-skill-points-spent").send(player); MMOCore.plugin.configManager.getSimpleMessage("no-skill-points-spent").send(player);
@ -361,10 +358,9 @@ public class SkillList extends EditableInventory {
return; return;
} }
for (ClassSkill skill : playerData.getProfess().getSkills())
for (ClassSkill skill : playerData.getProfess().getSkills()) {
playerData.setSkillLevel(skill.getSkill(), 1); playerData.setSkillLevel(skill.getSkill(), 1);
}
playerData.giveSkillPoints(spent); playerData.giveSkillPoints(spent);
playerData.setSkillReallocationPoints(playerData.getSkillReallocationPoints() - 1); playerData.setSkillReallocationPoints(playerData.getSkillReallocationPoints() - 1);
MMOCore.plugin.configManager.getSimpleMessage("skill-points-reallocated", "points", "" + playerData.getSkillPoints()).send(player); MMOCore.plugin.configManager.getSimpleMessage("skill-points-reallocated", "points", "" + playerData.getSkillPoints()).send(player);
@ -386,9 +382,7 @@ public class SkillList extends EditableInventory {
return; return;
} }
/* // Binding or unbinding skills.
* binding or unbinding skills.
*/
if (item.getFunction().equals("slot")) { if (item.getFunction().equals("slot")) {
int index = slotSlots.indexOf(context.getSlot()) + 1; int index = slotSlots.indexOf(context.getSlot()) + 1;
SkillSlot skillSlot = playerData.getProfess().getSkillSlot(index); SkillSlot skillSlot = playerData.getProfess().getSkillSlot(index);
@ -398,6 +392,7 @@ public class SkillList extends EditableInventory {
selected=playerData.getBoundSkill(index); selected=playerData.getBoundSkill(index);
return; return;
} }
// unbind if there is a current spell. // unbind if there is a current spell.
if (context.getClickType() == ClickType.RIGHT) { if (context.getClickType() == ClickType.RIGHT) {
if (!playerData.hasSkillBound(index)) { if (!playerData.hasSkillBound(index)) {
@ -405,7 +400,7 @@ public class SkillList extends EditableInventory {
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;
} }
if(!playerData.getProfess().getSkillSlot(index).canManuallyBind()){ if (!playerData.getProfess().getSkillSlot(index).canManuallyBind()) {
MMOCore.plugin.configManager.getSimpleMessage("cant-manually-bind").send(player); MMOCore.plugin.configManager.getSimpleMessage("cant-manually-bind").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;
@ -417,34 +412,30 @@ public class SkillList extends EditableInventory {
} }
if (!playerData.hasSkillUnlocked(selected)) { if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); MMOCore.plugin.configManager.getSimpleMessage("skill-level-not-met").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;
} }
if (!skillSlot.canManuallyBind()){ if (!skillSlot.canManuallyBind()) {
MMOCore.plugin.configManager.getSimpleMessage("cant-manually-bind").send(player); MMOCore.plugin.configManager.getSimpleMessage("cant-manually-bind").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;
} }
if (!skillSlot.acceptsSkill(selected)){ if (!skillSlot.acceptsSkill(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-compatible-skill").send(player); MMOCore.plugin.configManager.getSimpleMessage("not-compatible-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;
} }
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.bindSkill(index, selected); playerData.bindSkill(index, selected);
open(); open();
return; return;
} }
// Upgrading a player skill
/*
* upgrading a player skill
*/
if (item.getFunction().equals("upgrade")) { if (item.getFunction().equals("upgrade")) {
int shiftCost = ((UpgradeItem) item).shiftCost; int shiftCost = ((UpgradeItem) item).shiftCost;

View File

@ -34,7 +34,7 @@ public class ConfigManager {
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown; public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown, public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown,
pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown; pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown;
public int maxPartyLevelDifference, maxSlots, minCombatLevel, maxCombatLevelDifference; public int maxPartyLevelDifference, maxSkillSlots, minCombatLevel, maxCombatLevelDifference;
public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>(); public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>();
private final FileConfiguration messages; private final FileConfiguration messages;
@ -157,7 +157,7 @@ public class ConfigManager {
canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast"); canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast");
cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp"); cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp");
saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info"); saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info");
maxSlots = MMOCore.plugin.getConfig().getInt("max-slots"); maxSkillSlots = MMOCore.plugin.getConfig().getInt("max-skill-slots");
overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp"); overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp");
} }
@ -181,11 +181,11 @@ public class ConfigManager {
} }
public void loadDefaultFile(String path, String name) { public void loadDefaultFile(String path, String name) {
String newPath =""; String newPath = "";
if(!path.isEmpty()){ if (!path.isEmpty()) {
String[] subpaths = path.split("/"); String[] subpaths = path.split("/");
for (String subpath : subpaths) { for (String subpath : subpaths) {
newPath+="/"+subpath; newPath += "/" + subpath;
File folder = new File(MMOCore.plugin.getDataFolder() + (newPath)); File folder = new File(MMOCore.plugin.getDataFolder() + (newPath));
if (!folder.exists()) folder.mkdir(); if (!folder.exists()) folder.mkdir();
} }
@ -193,7 +193,6 @@ public class ConfigManager {
File file = new File(MMOCore.plugin.getDataFolder() + (newPath), name); File file = new File(MMOCore.plugin.getDataFolder() + (newPath), name);
if (!file.exists()) try { if (!file.exists()) try {
MMOCore.log("default/" + (path.isEmpty() ? "" : path + "/") + name);
Files.copy(MMOCore.plugin.getResource("default/" + (path.isEmpty() ? "" : path + "/") + name), file.getAbsoluteFile().toPath()); Files.copy(MMOCore.plugin.getResource("default/" + (path.isEmpty() ? "" : path + "/") + name), file.getAbsoluteFile().toPath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -33,7 +33,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
public void loadData(PlayerData data) { public void loadData(PlayerData data) {
FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig(); FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig();
//Reset stats linked to triggers. // Reset stats linked to triggers.
data.resetTriggerStats(); data.resetTriggerStats();
data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints())); data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
@ -70,8 +70,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
data.bindSkill(Integer.parseInt(key), skill); data.bindSkill(Integer.parseInt(key), skill);
} }
for ( for (String key : MMOCore.plugin.skillTreeManager.getAll().
String key : MMOCore.plugin.skillTreeManager.getAll().
stream(). stream().
map(skillTree -> skillTree.getId()). map(skillTree -> skillTree.getId()).
toList()) { toList()) {
@ -79,7 +78,6 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
} }
data.setSkillTreePoints("global", config.getInt("skill-tree-points.global", 0)); data.setSkillTreePoints("global", config.getInt("skill-tree-points.global", 0));
if (config.contains("times-claimed")) 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); ConfigurationSection section = config.getConfigurationSection("times-claimed." + key);
@ -193,7 +191,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
info.getNodeKeys().forEach(node -> config.set("class-info." + key + ".node-levels." + node, info.getNodeLevel(node))); info.getNodeKeys().forEach(node -> config.set("class-info." + key + ".node-levels." + node, info.getNodeLevel(node)));
info.getSkillTreePointsKeys().forEach(skillTreeId -> config.set("class-info." + key + ".skill-tree-points." + skillTreeId, info.getAttributeLevel(skillTreeId))); info.getSkillTreePointsKeys().forEach(skillTreeId -> config.set("class-info." + key + ".skill-tree-points." + skillTreeId, info.getAttributeLevel(skillTreeId)));
info.getBoundSkills().forEach((slot, skill) -> config.set("class-info." + key + ".bound-skills." + slot, skill)); info.getBoundSkills().forEach((slot, skill) -> config.set("class-info." + key + ".bound-skills." + slot, skill));
config.set("class-info." + key + ".unlocked-items", info.getUnlockedItems()); config.set("class-info." + key + ".unlocked-items", new ArrayList<>(info.getUnlockedItems()));
} }
file.save(); file.save();

View File

@ -20,6 +20,8 @@ public interface Unlockable {
*/ */
String getUnlockNamespacedKey(); String getUnlockNamespacedKey();
boolean isUnlockedByDefault();
void whenLocked(PlayerData playerData); void whenLocked(PlayerData playerData);
void whenUnlocked(PlayerData playerData); void whenUnlocked(PlayerData playerData);

View File

@ -9,12 +9,14 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.player.Unlockable;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
public class ClassSkill implements CooldownObject { public class ClassSkill implements CooldownObject, Unlockable {
private final RegisteredSkill skill; private final RegisteredSkill skill;
private final int unlockLevel, maxSkillLevel; private final int unlockLevel, maxSkillLevel;
private final boolean unlockedByDefault; private final boolean unlockedByDefault;
@ -56,6 +58,7 @@ public class ClassSkill implements CooldownObject {
} }
} }
@NotNull
public RegisteredSkill getSkill() { public RegisteredSkill getSkill() {
return skill; return skill;
} }
@ -72,10 +75,29 @@ public class ClassSkill implements CooldownObject {
return maxSkillLevel; return maxSkillLevel;
} }
@Override
public boolean isUnlockedByDefault() { public boolean isUnlockedByDefault() {
return unlockedByDefault; return unlockedByDefault;
} }
@Override
public String getUnlockNamespacedKey() {
return "skill:" + skill.getHandler().getId().toLowerCase();
}
@Override
public void whenLocked(PlayerData playerData) {
playerData.mapBoundSkills().forEach((slot, skill) -> {
if (skill.equals(getUnlockNamespacedKey().split(":")[1]))
playerData.unbindSkill(slot);
});
}
@Override
public void whenUnlocked(PlayerData playerData) {
}
/** /**
* This method can only override default modifiers and * This method can only override default modifiers and
* will throw an error when trying to define non existing modifiers * will throw an error when trying to define non existing modifiers

View File

@ -5,8 +5,6 @@ import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.player.Unlockable;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
@ -17,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
public class RegisteredSkill implements Unlockable { public class RegisteredSkill {
private final SkillHandler<?> handler; private final SkillHandler<?> handler;
private final String name; private final String name;
private final Map<String, LinearValue> defaultModifiers = new HashMap<>(); private final Map<String, LinearValue> defaultModifiers = new HashMap<>();
@ -65,24 +63,6 @@ public class RegisteredSkill implements Unlockable {
this.categories = new ArrayList<>(); this.categories = new ArrayList<>();
} }
@Override
public String getUnlockNamespacedKey() {
return "skill:" + handler.getId().toLowerCase();
}
@Override
public void whenLocked(PlayerData playerData) {
playerData.mapBoundSkills().forEach((slot, skill) -> {
if (skill.equals(getUnlockNamespacedKey().split(":")[1]))
playerData.unbindSkill(slot);
});
}
@Override
public void whenUnlocked(PlayerData playerData) {
}
public SkillHandler<?> getHandler() { public SkillHandler<?> getHandler() {
return handler; return handler;
} }

View File

@ -9,6 +9,7 @@ import net.Indyuce.mmocore.skill.ClassSkill;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -19,12 +20,10 @@ public class SkillSlot implements Unlockable {
private final List<String> lore; private final List<String> lore;
private final boolean isUnlockedByDefault; private final boolean isUnlockedByDefault;
private final boolean canManuallyBind; private final boolean canManuallyBind;
private final List<SkillModifierTrigger> skillBuffTriggers; private final List<SkillModifierTrigger> skillBuffTriggers = new ArrayList<>();
private final Material item;
private Material item;
public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, boolean isUnlockedByDefault, boolean canManuallyBind, List<SkillModifierTrigger> skillBuffTriggers) { public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, boolean isUnlockedByDefault, boolean canManuallyBind, List<SkillModifierTrigger> skillBuffTriggers) {
this.slot = slot; this.slot = slot;
@ -32,9 +31,10 @@ public class SkillSlot implements Unlockable {
this.formula = formula; this.formula = formula;
this.name = name; this.name = name;
this.lore = lore; this.lore = lore;
this.item = null;
this.canManuallyBind = canManuallyBind; this.canManuallyBind = canManuallyBind;
this.isUnlockedByDefault = isUnlockedByDefault; this.isUnlockedByDefault = isUnlockedByDefault;
this.skillBuffTriggers = skillBuffTriggers; this.skillBuffTriggers.addAll(skillBuffTriggers);
} }
public SkillSlot(ConfigurationSection section) { public SkillSlot(ConfigurationSection section) {
@ -42,12 +42,10 @@ public class SkillSlot implements Unlockable {
this.formula = section.contains("formula") ? section.getString("formula") : "true"; this.formula = section.contains("formula") ? section.getString("formula") : "true";
this.name = section.getString("name"); this.name = section.getString("name");
this.lore = section.getStringList("lore"); this.lore = section.getStringList("lore");
if (section.contains("item")) this.item = section.contains("item") ? Material.valueOf(section.getString("item")) : null;
this.item = Material.valueOf(section.getString("item"));
this.modelData = section.getInt("model-data", 0); this.modelData = section.getInt("model-data", 0);
isUnlockedByDefault = section.getBoolean("unlocked-by-default", true); this.isUnlockedByDefault = section.getBoolean("unlocked-by-default", true);
canManuallyBind = section.getBoolean("can-manually-bind", true); this.canManuallyBind = section.getBoolean("can-manually-bind", true);
skillBuffTriggers = new ArrayList<>();
if (section.contains("skill-buffs")) if (section.contains("skill-buffs"))
for (String skillBuff : section.getStringList("skill-buffs")) for (String skillBuff : section.getStringList("skill-buffs"))
if (skillBuff.startsWith("skill_buff")) if (skillBuff.startsWith("skill_buff"))
@ -66,6 +64,7 @@ public class SkillSlot implements Unlockable {
return lore; return lore;
} }
@Nullable
public Material getItem() { public Material getItem() {
return item; return item;
} }

View File

@ -39,21 +39,21 @@ public abstract class SkillCastingHandler extends BukkitRunnable implements List
@Override @Override
public void run() { public void run() {
if (!caster.isOnline() || caster.getPlayer().isDead()) if (!caster.isOnline() || caster.getPlayer().isDead()) {
caster.leaveSkillCasting(); caster.leaveSkillCasting();
else { return;
// Apply casting particles
if (caster.getProfess().getCastParticle() != null)
for (int k = 0; k < 2; k++) {
double a = (double) j++ / 5;
caster.getProfess().getCastParticle()
.display(caster.getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)));
}
// Apply casting mode-specific effects
onTick();
} }
// Apply casting particles
if (caster.getProfess().getCastParticle() != null)
for (int k = 0; k < 2; k++) {
double a = (double) j++ / 5;
caster.getProfess().getCastParticle()
.display(caster.getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)));
}
// Apply casting mode-specific effects
onTick();
} }
public abstract void onTick(); public abstract void onTick();

View File

@ -70,9 +70,8 @@ public class SkillTreeNode implements ExperienceObject {
throw new RuntimeException("You must only specifiy integers in lores."); throw new RuntimeException("You must only specifiy integers in lores.");
} }
String expTableId = config.getString("experience-table"); Validate.isTrue(config.contains("experience-table"), "You must specify an exp table");
Validate.notNull(expTableId, "You must specify an exp table for " + getFullId() + "."); this.experienceTable = MMOCore.plugin.experience.loadExperienceTable(config.get("experience-table"));
this.experienceTable = MMOCore.plugin.experience.getTableOrThrow(expTableId);
maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1; maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1;
maxChildren = config.contains("max-children") ? config.getInt("max-children") : 1; maxChildren = config.contains("max-children") ? config.getInt("max-children") : 1;
@ -121,7 +120,6 @@ public class SkillTreeNode implements ExperienceObject {
return softParents.containsKey(parent) || strongParents.containsKey(parent); return softParents.containsKey(parent) || strongParents.containsKey(parent);
} }
public int getMaxLevel() { public int getMaxLevel() {
return maxLevel; return maxLevel;
} }

View File

@ -70,7 +70,6 @@ public class Waypoint extends PostLoadObject implements Unlockable {
} }
} }
@Override @Override
protected void whenPostLoaded(@NotNull ConfigurationSection config) { protected void whenPostLoaded(@NotNull ConfigurationSection config) {
@ -213,6 +212,11 @@ public class Waypoint extends PostLoadObject implements Unlockable {
return "waypoint:" + getId(); return "waypoint:" + getId();
} }
@Override
public boolean isUnlockedByDefault() {
return hasOption(WaypointOption.DEFAULT);
}
@Override @Override
public void whenLocked(PlayerData playerData) { public void whenLocked(PlayerData playerData) {

View File

@ -197,8 +197,8 @@ death-exp-loss:
# Percentage of current EXP you lose when dying. # Percentage of current EXP you lose when dying.
percent: 30 percent: 30
#Maximum number of slot. This means that you can't unlock a slot greater than max-slots. (The slot count starts at 1 & end at max-slots). # Maximum number of skill slots. This means that you cannot unlock more than X skill slots.
max-slots: 8 max-skill-slots: 8
#If you want players to bound their passive skills. #If you want players to bound their passive skills.
#If false, all the passive skills unlocked will be active #If false, all the passive skills unlocked will be active

View File

@ -1,4 +1,11 @@
# Experience tables are separated into multiple items.
example_exp_table: example_exp_table:
# Every item is fully independent and has its own chance
# of dropping every time a player passes a level! When an
# item drops, all its triggers are called.
first_table_item: first_table_item:
# This item will drop every 3 level ups # This item will drop every 3 level ups
@ -7,13 +14,13 @@ example_exp_table:
# This item has a 80% chance to drop every 3 level ups # This item has a 80% chance to drop every 3 level ups
chance: 80 chance: 80
# Every successive fail in claiming the item will reduce # Every successive drop failure the item will reduce the
# the risk of failing future claims by X%. With a 80% # future risk by X%. With a 80% failure reduction rate,
# fail reduction rate, chances become: # risks become:
# - 80% # - 80%
# - 96% # - 96% (almost guaranteed)
# - 99.2% # - 99.2% (almost guaranteed+)
# - 99.84% # - 99.84% (almost guaranteed++)
# so on forever.. # so on forever..
# #
# This is better than just increasing the claim chance by a # This is better than just increasing the claim chance by a
@ -21,10 +28,13 @@ example_exp_table:
# just becomes/surpasses 100% at some point. # just becomes/surpasses 100% at some point.
fail-reduction: 80 fail-reduction: 80
# What happens when that item is claimed # What happens when that item is claimed. Does it give exp?
# Does it perform a command, unlocks a skill? etc
# You can find the list of available triggers on the wiki
triggers: triggers:
- 'exp{amount=20}' - 'exp{amount=20}'
# This is a second item, fully independent of the previous one.
second_table_item: second_table_item:
period: 2 period: 2
triggers: triggers:
@ -53,284 +63,3 @@ second_exp_table:
triggers: triggers:
- 'exp{amount=100}' - 'exp{amount=100}'
### Skill Tree
## MANA_REGENERATION
skilltree_mana_regeneration1:
mana_regeneration:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=1;type="FLAT"}'
skilltree_mana_regeneration2:
mana_regeneration:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
## HEALTH_REGENERATION
skilltree_health_regeneration1:
health_regeneration:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=1;type="FLAT"}'
skilltree_health_regeneration2:
health_regeneration:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
## COOLDOWN_REDUCTION
skilltree_cooldown_reduction5:
cooldown_reduction:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=5;type="FLAT"}'
skilltree_cooldown_reduction10:
cooldown_reduction:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=10;type="FLAT"}'
skilltree_cooldown_reduction15:
cooldown_reduction:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=15;type="FLAT"}'
## CRITICAL_STRIKE_CHANCE
skilltree_critical_strike_chance1:
critical_strike_chance:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=1;type="FLAT"}'
skilltree_critical_strike_chance2:
critical_strike_chance:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=2;type="FLAT"}'
skilltree_critical_strike_chance3:
critical_strike_chance:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=3;type="FLAT"}'
skilltree_critical_strike_chance5:
critical_strike_chance:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=5;type="FLAT"}'
## WEAPON_DAMAGE
skilltree_weapon_damage1:
weapon_damage:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=1;type="FLAT"}'
skilltree_weapon_damage2:
weapon_damage:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
skilltree_weapon_damage4:
weapon_damage:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=4;type="FLAT"}'
## DAMAGE_REDUCTION
skilltree_damage_reduction1:
weapon_damage:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=1;type="FLAT"}'
skilltree_damage_reduction2:
weapon_damage:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=2;type="FLAT"}'
## LIFESTEAL
skilltree_lifesteal1:
lifesteal:
triggers:
- 'stat{stat="LIFESTEAL";amount=1;type="FLAT"}'
skilltree_lifesteal2:
lifesteal:
triggers:
- 'stat{stat="LIFESTEAL";amount=2;type="FLAT"}'
skilltree_lifesteal3:
lifesteal:
triggers:
- 'stat{stat="LIFESTEAL";amount=3;type="FLAT"}'
## MAX_HEALTH
skilltree_max_health1:
max_health:
triggers:
- 'stat{stat="MAX_HEALTH";amount=1;type="FLAT"}'
skilltree_max_health2:
max_health:
triggers:
- 'stat{stat="MAX_HEALTH";amount=2;type="FLAT"}'
skilltree_max_health4:
max_health:
triggers:
- 'stat{stat="MAX_HEALTH";amount=4;type="FLAT"}'
skilltree_max_health5:
max_health:
triggers:
- 'stat{stat="MAX_HEALTH";amount=5;type="FLAT"}'
## MAGIC_DAMAGE
skilltree_magic_damage1:
magic_damage:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=1;type="FLAT"}'
skilltree_magic_damage2:
magic_damage:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=2;type="FLAT"}'
skilltree_magic_damage3:
magic_damage:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=3;type="FLAT"}'
## ATTACK_SPEED
skilltree_attack_speed5:
attack_speed:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=5;type="RELATIVE"}'
skilltree_attack_speed10:
attack_speed:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=10;type="RELATIVE"}'
skilltree_attack_speed15:
attack_speed:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=15;type="RELATIVE"}'
## PHYSICAL_DAMAGE_REDUCTION
skilltree_physical_damage_reduction5:
physical_damage_reduction:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=5;type="FLAT"}'
skilltree_physical_damage_reduction10:
physical_damage_reduction:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=10;type="FLAT"}'
skilltree_physical_damage_reduction15:
physical_damage_reduction:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=15;type="FLAT"}'
## PARRY_RATING
skilltree_parry_rating5:
parry_rating:
triggers:
- 'stat{stat="PARRY_RATING";amount=5;type="FLAT"}'
skilltree_parry_rating10:
parry_ratingn:
triggers:
- 'stat{stat="PARRY_RATING";amount=10;type="FLAT"}'
## KNOCKBACK_RESISTANCE
skilltree_knockback_resistance5:
knockback_resistance:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=0.05;type="FLAT"}'
skilltree_knockback_resistance10:
knockback_resistance:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=0.1;type="FLAT"}'
## DODGE_RATING
skilltree_dodge_rating2:
dodge_rating:
triggers:
- 'stat{stat="DODGE_RATING";amount=2;type="FLAT"}'
skilltree_dodge_rating3:
dodge_rating:
triggers:
- 'stat{stat="DODGE_RATING";amount=3;type="FLAT"}'
skilltree_dodge_rating5:
dodge_rating:
triggers:
- 'stat{stat="DODGE_RATING";amount=100;type="FLAT"}'
## SKILL_DAMAGE
skilltree_skill_damage5:
skill_damage:
triggers:
- 'stat{stat="SKILL_DAMAGE";amount=5;type="FLAT"}'
skilltree_skill_damage10:
skill_damage:
triggers:
- 'stat{stat="SKILL_DAMAGE";amount=10;type="FLAT"}'
## SPELL_VAMPIRISM
skilltree_spell_vampirism2:
spell_vampirism:
triggers:
- 'stat{stat="SPELL_VAMPIRISM";amount=2;type="FLAT"}'
skilltree_spell_vampirism6:
spell_vampirism:
triggers:
- 'stat{stat="SPELL_VAMPIRISM";amount=6;type="FLAT"}'
## ADDITIONAL_EXPERIENCE
skilltree_additional_experience2:
additional_experience:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=2;type="FLAT"}'
skilltree_additional_experience3:
additional_experience:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=3;type="FLAT"}'
skilltree_additional_experience5:
additional_experience:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=5;type="FLAT"}'
## MAGIC_DAMAGE_REDUCTION
skilltree_magic_damage_reduction5:
magic_damage_reduction:
triggers:
- 'stat{stat="MAGIC_DAMAGE_REDUCTION";amount=5;type="FLAT"}'
skilltree_magic_damage_reduction10:
magic_damage_reduction:
triggers:
- 'stat{stat="MAGIC_DAMAGE_REDUCTION";amount=10;type="FLAT"}'
## SKILL_CRITICAL_STRIKE_CHANCE
skilltree_skill_critical_strike_chance5:
skill_critical_strike_chance:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=5;type="FLAT"}'
skilltree_skill_critical_strike_chance10:
skill_critical_strike_chance:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=10;type="FLAT"}'
skilltree_skill_critical_strike_chance15:
skill_critical_strike_chance:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=15;type="FLAT"}'
## ARROW_VELOCITY
skilltree_arrow_velocity10:
arrow_velocity:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=10;type="RELATIVE"}'
skilltree_arrow_velocity15:
arrow_velocity:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=15;type="RELATIVE"}'
skilltree_arrow_velocity25:
arrow_velocity:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=25;type="RELATIVE"}'
## MOVEMENT_SPEED
skilltree_movement_speed2:
movement_speed:
triggers:
- 'stat{stat="MOVEMENT_SPEED";amount=10;type="RELATIVE"}'
skilltree_movement_speed6:
movement_speed:
triggers:
- 'stat{stat="MOVEMENT_SPEED";amount=10;type="RELATIVE"}'
## PROJECTILE_DAMAGE
skilltree_projectile_damage2:
projectile_damage:
triggers:
- 'stat{stat="PROJECTILE_DAMAGE";amount=10;type="FLAT"}'
skilltree_projectile_damage6:
projectile_damage:
triggers:
- 'stat{stat="PROJECTILE_DAMAGE";amount=6;type="FLAT"}'

View File

@ -200,7 +200,7 @@ no-class-skill: '&cYour class has no skill.'
not-enough-skill-points: '&cYou need one skill point.' not-enough-skill-points: '&cYou need one skill point.'
not-enough-skill-points-shift: '&cYou need {shift_points} skill points.' not-enough-skill-points-shift: '&cYou need {shift_points} skill points.'
upgrade-skill: '&eYour &6{skill} &eis now Level &6{level}&e!' upgrade-skill: '&eYour &6{skill} &eis now Level &6{level}&e!'
not-unlocked-skill: '&cYou have not unlocked that skill yet.' skill-level-not-met: '&cYou cannot use this skill yet.'
no-skill-bound: '&cYou don''t have any skill bound to this slot.' no-skill-bound: '&cYou don''t have any skill bound to this slot.'
not-compatible-skill: '&cThe selected skill is not compatible with this slot.' not-compatible-skill: '&cThe selected skill is not compatible with this slot.'
cant-manually-bind: "&cYou can't manually bind/unbind a skill to this slot." cant-manually-bind: "&cYou can't manually bind/unbind a skill to this slot."

View File

@ -16,12 +16,15 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_cooldown_reduction5 experience-table:
first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (5%)" - "&eReduces item/class skill cooldowns (5%)"
1: 1:
- "&eReduces cooldowns of item and player skills (5%)" - "&eReduces item/class skill cooldowns (5%)"
@ -30,30 +33,36 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_cooldown_reduction10 experience-table:
first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=10;type="FLAT"}'
coordinates: coordinates:
x: -2 x: -2
y: -2 y: -2
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (10%)" - "&eReduces item/class skill cooldowns (10%)"
1: 1:
- "&eReduces cooldowns of item and player skills (10%)" - "&eReduces item/class skill cooldowns (20%)"
a3: a3:
name: 'Cooldown Reduction' name: 'Cooldown Reduction'
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_cooldown_reduction15 experience-table:
first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=15;type="FLAT"}'
coordinates: coordinates:
x: -1 x: -1
y: -2 y: -2
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (15%)" - "&eReduces item/class skill cooldowns (15%)"
1: 1:
- "&eReduces cooldowns of item and player skills (15%)" - "&eReduces item/class skill cooldowns (30%)"
### B ### B
@ -62,7 +71,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_critical_strike_chance1 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=1;type="FLAT"}'
coordinates: coordinates:
x: 0 x: 0
y: -2 y: -2
@ -70,14 +82,17 @@ nodes:
0: 0:
- "&eCritical Strikes deal more damage in % chance" - "&eCritical Strikes deal more damage in % chance"
1: 1:
- "&eCritical Strikes deal more damage in +%2 chance" - "&eCritical Strikes deal more damage in +%1 chance"
b2: b2:
name: 'Critical Strike Chance' name: 'Critical Strike Chance'
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_critical_strike_chance2 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 0 x: 0
y: -1 y: -1
@ -92,7 +107,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 2 max-children: 2
experience-table: skilltree_critical_strike_chance3 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=3;type="FLAT"}'
coordinates: coordinates:
x: 0 x: 0
y: 0 y: 0
@ -109,7 +127,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_lifesteal1 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=1;type="FLAT"}'
coordinates: coordinates:
x: -1 x: -1
y: 0 y: 0
@ -124,7 +145,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_lifesteal2 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=2;type="FLAT"}'
coordinates: coordinates:
x: -2 x: -2
y: 0 y: 0
@ -139,7 +163,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_lifesteal2 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=3;type="FLAT"}'
coordinates: coordinates:
x: -3 x: -3
y: 0 y: 0
@ -156,7 +183,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_damage_reduction1 experience-table:
first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=1;type="FLAT"}'
coordinates: coordinates:
x: 0 x: 0
y: 1 y: 1
@ -171,7 +201,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 2 max-children: 2
experience-table: skilltree_damage_reduction2 experience-table:
first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 0 x: 0
y: 2 y: 2
@ -186,7 +219,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_damage_reduction2 experience-table:
first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: -1 x: -1
y: 2 y: 2
@ -203,7 +239,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_health_regeneration1 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=1;type="FLAT"}'
coordinates: coordinates:
x: -2 x: -2
y: 2 y: 2
@ -218,7 +257,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_health_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: -3 x: -3
y: 2 y: 2
@ -233,7 +275,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_health_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: -3 x: -3
y: 1 y: 1
@ -250,7 +295,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_mana_regeneration1 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=1;type="FLAT"}'
coordinates: coordinates:
x: 1 x: 1
y: 2 y: 2
@ -265,7 +313,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_mana_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 2 x: 2
y: 2 y: 2
@ -280,7 +331,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_mana_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 3 x: 3
y: 2 y: 2
@ -297,7 +351,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_magic_damage1 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=1;type="FLAT"}'
coordinates: coordinates:
x: 3 x: 3
y: 1 y: 1
@ -312,7 +369,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_magic_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 4 x: 4
y: 1 y: 1
@ -327,7 +387,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_magic_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 4 x: 4
y: 0 y: 0
@ -344,7 +407,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_max_health2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAX_HEALTH";amount=2;type="RELATIVE"}'
coordinates: coordinates:
x: 4 x: 4
y: -1 y: -1
@ -359,7 +425,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_max_health4 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAX_HEALTH";amount=4;type="RELATIVE"}'
coordinates: coordinates:
x: 4 x: 4
y: -2 y: -2
@ -374,7 +443,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_max_health4 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAX_HEALTH";amount=4;type="RELATIVE"}'
coordinates: coordinates:
x: 3 x: 3
y: -2 y: -2
@ -391,7 +463,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_weapon_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
coordinates: coordinates:
x: 2 x: 2
y: -2 y: -2
@ -406,7 +481,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_weapon_damage4 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=4;type="FLAT"}'
coordinates: coordinates:
x: 2 x: 2
y: -1 y: -1
@ -421,7 +499,10 @@ nodes:
size: 1 size: 1
point-consumed: 1 point-consumed: 1
max-children: 1 max-children: 1
experience-table: skilltree_weapon_damage4 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=4;type="FLAT"}'
coordinates: coordinates:
x: 2 x: 2
y: 0 y: 0
@ -432,8 +513,6 @@ nodes:
- "&eAdditional on-hit weapon damage in +%4" - "&eAdditional on-hit weapon damage in +%4"
paths: paths:
path1: path1:
x: 2 x: 2

View File

@ -19,7 +19,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_mana_regeneration1 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +1" - "&eMana regen in pts/sec +1"
@ -38,8 +41,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_mana_regeneration2 first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +2" - "&eMana regen in pts/sec +2"
@ -58,8 +63,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_mana_regeneration2 first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +2" - "&eMana regen in pts/sec +2"
@ -77,8 +84,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_health_regeneration1 first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eHealth regen in pts/sec +1" - "&eHealth regen in pts/sec +1"
@ -98,8 +107,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_health_regeneration2 first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eHealth regen in pts/sec +2" - "&eHealth regen in pts/sec +2"
@ -119,8 +130,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_health_regeneration2 first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eHealth regen in pts/sec +2" - "&eHealth regen in pts/sec +2"
@ -138,8 +151,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_cooldown_reduction5 first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (5%)" - "&eReduces cooldowns of item and player skills (5%)"
@ -159,8 +174,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_cooldown_reduction10 first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (10%)" - "&eReduces cooldowns of item and player skills (10%)"
@ -180,8 +197,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_cooldown_reduction15 first_table_item:
triggers:
- 'stat{stat="COOLDOWN_REDUCTION";amount=15;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces cooldowns of item and player skills (15%)" - "&eReduces cooldowns of item and player skills (15%)"
@ -204,8 +223,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_critical_strike_chance1 first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in +%2 chance" - "&eCritical Strikes deal more damage in +%2 chance"
@ -225,8 +246,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_critical_strike_chance2 first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in % chance" - "&eCritical Strikes deal more damage in % chance"
@ -246,8 +269,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_critical_strike_chance5 first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in % chance" - "&eCritical Strikes deal more damage in % chance"
@ -269,8 +294,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_damage_reduction1 first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces damage from any source in %." - "&eReduces damage from any source in %."
@ -290,8 +317,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_damage_reduction2 first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces damage from any source in %." - "&eReduces damage from any source in %."
@ -311,8 +340,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_damage_reduction2 first_table_item:
triggers:
- 'stat{stat="DAMAGE_REDUCTION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces damage from any source in %." - "&eReduces damage from any source in %."
@ -333,8 +364,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_weapon_damage1 first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%1."
@ -354,8 +387,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_weapon_damage2 first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%2." - "&eAdditional on-hit weapon damage in +%2."
@ -375,8 +410,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_weapon_damage2 first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%2." - "&eAdditional on-hit weapon damage in +%2."
@ -398,8 +435,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_lifesteal3 first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting weapon damage." - "&ePercentage of damage you gain back as health when inflicting weapon damage."
@ -420,8 +459,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_max_health5 first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional amount of health in +%5" - "&eAdditional amount of health in +%5"
@ -441,8 +482,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
point-consumed: 1 experience-table:
experience-table: skilltree_magic_damage3 first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional magic skill damage in +%3" - "&eAdditional magic skill damage in +%3"

View File

@ -19,7 +19,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_mana_regeneration1 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +1" - "&eMana regen in pts/sec +1"
@ -38,7 +41,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_mana_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +2" - "&eMana regen in pts/sec +2"
@ -57,7 +63,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_mana_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MANA_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eMana regen in pts/sec +2" - "&eMana regen in pts/sec +2"
@ -79,7 +88,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_damage5 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_DAMAGE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional ability damage in +%5" - "&eAdditional ability damage in +%5"
@ -98,7 +110,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_damage5 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_DAMAGE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional ability damage in +%5" - "&eAdditional ability damage in +%5"
@ -117,7 +132,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_damage10 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_DAMAGE";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional ability damage in +%10" - "&eAdditional ability damage in +%10"
@ -139,7 +157,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_spell_vampirism2 experience-table:
first_table_item:
triggers:
- 'stat{stat="SPELL_VAMPIRISM";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting skill damage +%2" - "&ePercentage of damage you gain back as health when inflicting skill damage +%2"
@ -158,7 +179,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_spell_vampirism2 experience-table:
first_table_item:
triggers:
- 'stat{stat="SPELL_VAMPIRISM";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting skill damage +%2" - "&ePercentage of damage you gain back as health when inflicting skill damage +%2"
@ -177,7 +201,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_spell_vampirism6 experience-table:
first_table_item:
triggers:
- 'stat{stat="SPELL_VAMPIRISM";amount=6;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting skill damage +%6" - "&ePercentage of damage you gain back as health when inflicting skill damage +%6"
@ -199,7 +226,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience2 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%2" - "&eAdditional MMOCore main class experience +%2"
@ -218,7 +248,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience3 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%3" - "&eAdditional MMOCore main class experience +%3"
@ -237,7 +270,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience5 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%5" - "&eAdditional MMOCore main class experience +%5"
@ -259,7 +295,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage_reduction5 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE_REDUCTION";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduce magic damage dealt by potions %5" - "&eReduce magic damage dealt by potions %5"
@ -278,7 +317,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage_reduction5 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE_REDUCTION";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduce magic damage dealt by potions %5" - "&eReduce magic damage dealt by potions %5"
@ -297,7 +339,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage_reduction10 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE_REDUCTION";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduce magic damage dealt by potions %10" - "&eReduce magic damage dealt by potions %10"
@ -319,7 +364,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_critical_strike_chance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eIncreases the chance of dealing skill crits +%5" - "&eIncreases the chance of dealing skill crits +%5"
@ -338,7 +386,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_critical_strike_chance10 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eIncreases the chance of dealing skill crits +%10" - "&eIncreases the chance of dealing skill crits +%10"
@ -357,7 +408,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_skill_critical_strike_chance15 experience-table:
first_table_item:
triggers:
- 'stat{stat="SKILL_CRITICAL_STRIKE_CHANCE";amount=15;type="FLAT"}'
lores: lores:
0: 0:
- "&eIncreases the chance of dealing skill crits +%15" - "&eIncreases the chance of dealing skill crits +%15"
@ -379,7 +433,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage1 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional magic skill damage in +%1" - "&eAdditional magic skill damage in +%1"
@ -398,7 +455,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional magic skill damage in +%2" - "&eAdditional magic skill damage in +%2"
@ -417,7 +477,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_magic_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MAGIC_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional magic skill damage in +%2" - "&eAdditional magic skill damage in +%2"

View File

@ -19,7 +19,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience2 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%2" - "&eAdditional MMOCore main class experience +%2"
@ -38,7 +41,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience3 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%3" - "&eAdditional MMOCore main class experience +%3"
@ -57,7 +63,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_additional_experience5 experience-table:
first_table_item:
triggers:
- 'stat{stat="ADDITIONAL_EXPERIENCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional MMOCore main class experience +%5" - "&eAdditional MMOCore main class experience +%5"
@ -79,7 +88,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_arrow_velocity10 experience-table:
first_table_item:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=10;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eDetermines how far your weapon can shoot +%10" - "&eDetermines how far your weapon can shoot +%10"
@ -98,7 +110,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_arrow_velocity15 experience-table:
first_table_item:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=15;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eDetermines how far your weapon can shoot +%15" - "&eDetermines how far your weapon can shoot +%15"
@ -117,7 +132,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_arrow_velocity25 experience-table:
first_table_item:
triggers:
- 'stat{stat="ARROW_VELOCITY";amount=25;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eDetermines how far your weapon can shoot +%25" - "&eDetermines how far your weapon can shoot +%25"
@ -139,7 +157,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_lifesteal1 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting weapon damage +%1" - "&ePercentage of damage you gain back as health when inflicting weapon damage +%1"
@ -158,7 +179,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_lifesteal2 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting weapon damage +%2" - "&ePercentage of damage you gain back as health when inflicting weapon damage +%2"
@ -177,7 +201,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_lifesteal2 experience-table:
first_table_item:
triggers:
- 'stat{stat="LIFESTEAL";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&ePercentage of damage you gain back as health when inflicting weapon damage +%2" - "&ePercentage of damage you gain back as health when inflicting weapon damage +%2"
@ -199,7 +226,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%5" - "&eThe chance of you to block the knockback +%5"
@ -218,7 +248,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%5" - "&eThe chance of you to block the knockback +%5"
@ -237,7 +270,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance10 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%5" - "&eThe chance of you to block the knockback +%5"
@ -259,7 +295,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_critical_strike_chance2 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in +%2 chance" - "&eCritical Strikes deal more damage in +%2 chance"
@ -278,7 +317,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_critical_strike_chance3 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in +%3 chance" - "&eCritical Strikes deal more damage in +%3 chance"
@ -297,7 +339,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_critical_strike_chance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="CRITICAL_STRIKE_CHANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eCritical Strikes deal more damage in +%5 chance" - "&eCritical Strikes deal more damage in +%5 chance"
@ -319,7 +364,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_movement_speed2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MOVEMENT_SPEED";amount=2;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eMovement Speed increase walk speed. +%2" - "&eMovement Speed increase walk speed. +%2"
@ -338,7 +386,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_movement_speed2 experience-table:
first_table_item:
triggers:
- 'stat{stat="MOVEMENT_SPEED";amount=2;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eMovement Speed increase walk speed. +%2" - "&eMovement Speed increase walk speed. +%2"
@ -357,7 +408,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_movement_speed6 experience-table:
first_table_item:
triggers:
- 'stat{stat="MOVEMENT_SPEED";amount=6;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eMovement Speed increase walk speed. +%6" - "&eMovement Speed increase walk speed. +%6"
@ -379,7 +433,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_projectile_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="PROJECTILE_DAMAGE";amount=2;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eAdditional skill/weapon projectile damage +%2" - "&eAdditional skill/weapon projectile damage +%2"
@ -398,7 +455,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_projectile_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="PROJECTILE_DAMAGE";amount=2;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eAdditional skill/weapon projectile damage +%2" - "&eAdditional skill/weapon projectile damage +%2"
@ -417,7 +477,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_projectile_damage6 experience-table:
first_table_item:
triggers:
- 'stat{stat="PROJECTILE_DAMAGE";amount=6;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eAdditional skill/weapon projectile damage +%6" - "&eAdditional skill/weapon projectile damage +%6"

View File

@ -19,7 +19,10 @@ nodes:
is-root: true is-root: true
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_attack_speed5 experience-table:
first_table_item:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=5;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eThe speed at which your weapon strikes. +%5" - "&eThe speed at which your weapon strikes. +%5"
@ -38,7 +41,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_attack_speed10 experience-table:
first_table_item:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=10;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eThe speed at which your weapon strikes. +%10" - "&eThe speed at which your weapon strikes. +%10"
@ -57,7 +63,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_attack_speed15 experience-table:
first_table_item:
triggers:
- 'stat{stat="ATTACK_SPEED";amount=15;type="RELATIVE"}'
lores: lores:
0: 0:
- "&eThe speed at which your weapon strikes. +%15" - "&eThe speed at which your weapon strikes. +%15"
@ -79,12 +88,15 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_health_regeneration1 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eCCC" - "&eIncreases health regeneration by 1%"
1: 1:
- "&eCCC" - "&eIncreases health regeneration by 1%"
b2: b2:
name: 'Health Regeneration' name: 'Health Regeneration'
coordinates: coordinates:
@ -98,12 +110,15 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_health_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eCCC" - "&eIncreases health regeneration by 1%"
1: 1:
- "&eCCC" - "&eIncreases health regeneration by 1%"
b3: b3:
name: 'Health Regeneration' name: 'Health Regeneration'
coordinates: coordinates:
@ -117,12 +132,15 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_health_regeneration2 experience-table:
first_table_item:
triggers:
- 'stat{stat="HEALTH_REGENERATION";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eCCC" - "&eIncreases health regeneration by 2%"
1: 1:
- "&eCCC" - "&eIncreases health regeneration by 2%"
## C ## C
@ -139,7 +157,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_physical_damage_reduction5 experience-table:
first_table_item:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces physical damage In -%5" - "&eReduces physical damage In -%5"
@ -158,7 +179,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_physical_damage_reduction10 experience-table:
first_table_item:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces physical damage In -%10" - "&eReduces physical damage In -%10"
@ -177,7 +201,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_physical_damage_reduction15 experience-table:
first_table_item:
triggers:
- 'stat{stat="PHYSICAL_DAMAGE_REDUCTION";amount=15;type="FLAT"}'
lores: lores:
0: 0:
- "&eReduces physical damage In -%15" - "&eReduces physical damage In -%15"
@ -199,7 +226,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_parry_rating5 experience-table:
first_table_item:
triggers:
- 'stat{stat="PARRY_RATING";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%5" - "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%5"
@ -218,7 +248,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_parry_rating5 experience-table:
first_table_item:
triggers:
- 'stat{stat="PARRY_RATING";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%5" - "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%5"
@ -237,7 +270,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_parry_rating10 experience-table:
first_table_item:
triggers:
- 'stat{stat="PARRY_RATING";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%10" - "&eThe chance to parry an attack. Parrying negates the damage and knocks the attacker back +%10"
@ -259,7 +295,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%5" - "&eThe chance of you to block the knockback +%5"
@ -278,7 +317,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance5 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%5" - "&eThe chance of you to block the knockback +%5"
@ -297,7 +339,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_knockback_resistance10 experience-table:
first_table_item:
triggers:
- 'stat{stat="KNOCKBACK_RESISTANCE";amount=10;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe chance of you to block the knockback +%10" - "&eThe chance of you to block the knockback +%10"
@ -319,7 +364,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_dodge_rating2 experience-table:
first_table_item:
triggers:
- 'stat{stat="DODGE_RATING";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%2" - "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%2"
@ -338,7 +386,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_dodge_rating3 experience-table:
first_table_item:
triggers:
- 'stat{stat="DODGE_RATING";amount=3;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%3" - "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%3"
@ -357,7 +408,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_dodge_rating5 experience-table:
first_table_item:
triggers:
- 'stat{stat="DODGE_RATING";amount=5;type="FLAT"}'
lores: lores:
0: 0:
- "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%5" - "&eThe change to dodge an attack. Dodging completely negates the attack damage. +%5"
@ -379,7 +433,10 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_weapon_damage1 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=1;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%1."
@ -398,12 +455,15 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_weapon_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%2."
1: 1:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%2."
g3: g3:
name: 'Weapon Damage' name: 'Weapon Damage'
coordinates: coordinates:
@ -417,12 +477,15 @@ nodes:
max-level: 1 max-level: 1
size: 1 size: 1
point-consumed: 1 point-consumed: 1
experience-table: skilltree_weapon_damage2 experience-table:
first_table_item:
triggers:
- 'stat{stat="WEAPON_DAMAGE";amount=2;type="FLAT"}'
lores: lores:
0: 0:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%2."
1: 1:
- "&eAdditional on-hit weapon damage in +%1." - "&eAdditional on-hit weapon damage in +%2."