forked from Upstream/mmocore
Skill combos merge
This commit is contained in:
commit
bfb33cd7a7
@ -13,7 +13,8 @@ public enum SoundEvent {
|
||||
SELECT_CLASS,
|
||||
LEVEL_ATTRIBUTE,
|
||||
RESET_ATTRIBUTES,
|
||||
NOT_ENOUGH_POINTS,
|
||||
RESET_SKILLS
|
||||
,NOT_ENOUGH_POINTS,
|
||||
CANCEL_QUEST,
|
||||
START_QUEST,
|
||||
CLOSE_LOOT_CHEST,
|
||||
|
@ -77,7 +77,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
*/
|
||||
@Nullable
|
||||
private PlayerClass profess;
|
||||
private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints;// skillReallocationPoints,
|
||||
private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints;
|
||||
private double experience;
|
||||
private double mana, stamina, stellium;
|
||||
private Guild guild;
|
||||
@ -416,6 +416,19 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return skillPoints;
|
||||
}
|
||||
|
||||
public void giveSkillReallocationPoints(int value) {
|
||||
skillReallocationPoints+=value;
|
||||
}
|
||||
|
||||
public int countSkillPointsWhenReallocate() {
|
||||
int sum = 0;
|
||||
for(ClassSkill skill:getProfess().getSkills()) {
|
||||
//0 if the skill is level 1(just unlocked) or 0 locked.
|
||||
sum+=Math.max(0,getSkillLevel(skill.getSkill())-1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int getAttributePoints() {
|
||||
return attributePoints;
|
||||
}
|
||||
@ -531,6 +544,14 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
attributeReallocationPoints = Math.max(0, value);
|
||||
}
|
||||
|
||||
public void setSkillReallocationPoints(int value) {
|
||||
skillReallocationPoints = Math.max(0, value);
|
||||
}
|
||||
|
||||
public int getSkillReallocationPoints() {
|
||||
return skillReallocationPoints;
|
||||
}
|
||||
|
||||
public void setSkillPoints(int value) {
|
||||
skillPoints = Math.max(0, value);
|
||||
}
|
||||
@ -1038,7 +1059,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
public void setBoundSkill(int slot, ClassSkill skill) {
|
||||
Validate.notNull(skill, "Skill cannot be null");
|
||||
if (boundSkills.size() < 6)
|
||||
if (boundSkills.size() < getProfess().getMaxBoundSkills())
|
||||
boundSkills.add(skill);
|
||||
else
|
||||
boundSkills.set(slot, skill);
|
||||
|
@ -31,12 +31,15 @@ import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
|
||||
import net.Indyuce.mmocore.player.stats.StatInfo;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import net.Indyuce.mmocore.skill.cast.KeyCombo;
|
||||
import net.Indyuce.mmocore.skill.cast.PlayerKey;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -65,10 +68,16 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
@NotNull
|
||||
private final CastingParticle castParticle;
|
||||
|
||||
private final int maxBoundSkills;
|
||||
private final List<PassiveSkill> classScripts = new LinkedList();
|
||||
private final Map<String, LinearValue> stats = new HashMap<>();
|
||||
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
|
||||
private final List<Subclass> subclasses = new ArrayList<>();
|
||||
private final List<PassiveSkill> classScripts = new LinkedList<>();
|
||||
|
||||
// If the class redefines its own key combos.
|
||||
private final Map<KeyCombo, Integer> combos = new HashMap<>();
|
||||
private int longestCombo;
|
||||
|
||||
private final Map<PlayerResource, ResourceRegeneration> resourceHandlers = new HashMap<>();
|
||||
|
||||
@Deprecated
|
||||
@ -110,7 +119,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
? MMOCore.plugin.experience.getCurveOrThrow(
|
||||
config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
|
||||
: ExpCurve.DEFAULT;
|
||||
|
||||
maxBoundSkills = config.getInt("max-bound-skills", 6);
|
||||
ExperienceTable expTable = null;
|
||||
if (config.contains("exp-table"))
|
||||
try {
|
||||
@ -132,6 +141,23 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load script '" + key + "' from class '" + id + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
// Load different combos
|
||||
if (config.contains("key-combos"))
|
||||
for (String key : config.getConfigurationSection("key-combos").getKeys(false))
|
||||
try {
|
||||
int spellSlot = Integer.valueOf(key);
|
||||
Validate.isTrue(spellSlot >= 0, "Spell slot must be at least 0");
|
||||
Validate.isTrue(!combos.values().contains(spellSlot), "There is already a key combo with the same skill slot");
|
||||
KeyCombo combo = new KeyCombo();
|
||||
for (String str : config.getStringList("key-combos." + key))
|
||||
combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str)));
|
||||
|
||||
combos.put(combo, spellSlot);
|
||||
longestCombo = Math.max(longestCombo, combo.countKeys());
|
||||
} catch (RuntimeException exception) {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load key combo '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
if (config.contains("triggers"))
|
||||
for (String key : config.getConfigurationSection("triggers").getKeys(false))
|
||||
try {
|
||||
@ -227,7 +253,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
this.icon = new ItemStack(material);
|
||||
setOption(ClassOption.DISPLAY, false);
|
||||
setOption(ClassOption.DEFAULT, false);
|
||||
|
||||
maxBoundSkills = 6;
|
||||
for (PlayerResource resource : PlayerResource.values())
|
||||
resourceHandlers.put(resource, new ResourceRegeneration(resource));
|
||||
}
|
||||
@ -283,6 +309,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
return expCurve;
|
||||
}
|
||||
|
||||
public int getMaxBoundSkills() {
|
||||
return maxBoundSkills;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ExperienceTable getExperienceTable() {
|
||||
return Objects.requireNonNull(expTable, "Class has no exp table");
|
||||
@ -406,6 +436,15 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
return stats.keySet();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<KeyCombo, Integer> getKeyCombos() {
|
||||
return combos;
|
||||
}
|
||||
|
||||
public int getLongestCombo() {
|
||||
return longestCombo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LinearValue getStatInfo(String stat) {
|
||||
LinearValue found = stats.get(stat);
|
||||
|
@ -50,6 +50,7 @@ public class CommandVerbose {
|
||||
|
||||
public enum CommandType {
|
||||
ATTRIBUTE,
|
||||
SKILL,
|
||||
CLASS,
|
||||
EXPERIENCE,
|
||||
LEVEL,
|
||||
|
@ -6,33 +6,35 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class AdminCommandTreeNode extends CommandTreeNode {
|
||||
public AdminCommandTreeNode(CommandTreeNode parent) {
|
||||
super(parent, "admin");
|
||||
|
||||
addChild(new HideActionBarCommandTreeNode(this));
|
||||
addChild(new NoCooldownCommandTreeNode(this));
|
||||
addChild(new ResetCommandTreeNode(this));
|
||||
addChild(new InfoCommandTreeNode(this));
|
||||
addChild(new ClassCommandTreeNode(this));
|
||||
addChild(new ForceClassCommandTreeNode(this));
|
||||
addChild(new ExportDataTreeNode(this));
|
||||
public AdminCommandTreeNode(CommandTreeNode parent) {
|
||||
super(parent, "admin");
|
||||
|
||||
addChild(new ExperienceCommandTreeNode(this));
|
||||
addChild(new LevelCommandTreeNode(this));
|
||||
addChild(new AttributeCommandTreeNode(this));
|
||||
addChild(new HideActionBarCommandTreeNode(this));
|
||||
addChild(new NoCooldownCommandTreeNode(this));
|
||||
addChild(new ResetCommandTreeNode(this));
|
||||
addChild(new InfoCommandTreeNode(this));
|
||||
addChild(new ClassCommandTreeNode(this));
|
||||
addChild(new ForceClassCommandTreeNode(this));
|
||||
addChild(new ExportDataTreeNode(this));
|
||||
|
||||
addChild(new PointsCommandTreeNode("skill", this, PlayerData::setSkillPoints, PlayerData::giveSkillPoints, PlayerData::getSkillPoints));
|
||||
addChild(new PointsCommandTreeNode("class", this, PlayerData::setClassPoints, PlayerData::giveClassPoints, PlayerData::getClassPoints));
|
||||
addChild(new PointsCommandTreeNode("attribute", this, PlayerData::setAttributePoints, PlayerData::giveAttributePoints, PlayerData::getAttributePoints));
|
||||
addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints));
|
||||
addChild(new PointsCommandTreeNode("skill-tree-realloc",this,PlayerData::setSkillTreeReallocationPoints,PlayerData::giveSkillTreeReallocationPoints,PlayerData::getSkillTreeReallocationPoints));
|
||||
addChild(new SkillTreePointsCommandTreeNode(this,(playerData,val,id)->playerData.setSkillTreePoints(id,val),(playerData, val, id)->playerData.giveSkillTreePoints(id,val),(playerData,id)->playerData.getSkillTreePoint(id)));
|
||||
for (PlayerResource res : PlayerResource.values())
|
||||
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
|
||||
}
|
||||
addChild(new ExperienceCommandTreeNode(this));
|
||||
addChild(new LevelCommandTreeNode(this));
|
||||
addChild(new AttributeCommandTreeNode(this));
|
||||
addChild(new SkillCommandTreeNode(this));
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandSender sender, String[] args) {
|
||||
return CommandResult.THROW_USAGE;
|
||||
}
|
||||
addChild(new PointsCommandTreeNode("skill", this, PlayerData::setSkillPoints, PlayerData::giveSkillPoints, PlayerData::getSkillPoints));
|
||||
addChild(new PointsCommandTreeNode("class", this, PlayerData::setClassPoints, PlayerData::giveClassPoints, PlayerData::getClassPoints));
|
||||
addChild(new PointsCommandTreeNode("attribute", this, PlayerData::setAttributePoints, PlayerData::giveAttributePoints, PlayerData::getAttributePoints));
|
||||
addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints));
|
||||
addChild(new PointsCommandTreeNode("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints));
|
||||
addChild(new PointsCommandTreeNode("skill-tree-realloc", this, PlayerData::setSkillTreeReallocationPoints, PlayerData::giveSkillTreeReallocationPoints, PlayerData::getSkillTreeReallocationPoints));
|
||||
|
||||
for (PlayerResource res : PlayerResource.values())
|
||||
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandSender sender, String[] args) {
|
||||
return CommandResult.THROW_USAGE;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
package net.Indyuce.mmocore.command.rpg.admin;
|
||||
|
||||
import io.lumine.mythic.lib.command.api.CommandTreeNode;
|
||||
import io.lumine.mythic.lib.command.api.Parameter;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
|
||||
public class SkillCommandTreeNode extends CommandTreeNode {
|
||||
public SkillCommandTreeNode(CommandTreeNode parent) {
|
||||
super(parent, "skill");
|
||||
|
||||
addChild(new ActionCommandTreeNode(this, "give", (old, amount) -> old + amount));
|
||||
addChild(new ActionCommandTreeNode(this, "set", (old, amount) -> amount));
|
||||
}
|
||||
|
||||
|
||||
public class ActionCommandTreeNode extends CommandTreeNode {
|
||||
private final BiFunction<Integer, Integer, Integer> change;
|
||||
|
||||
public ActionCommandTreeNode(CommandTreeNode parent, String type, BiFunction<Integer, Integer, Integer> change) {
|
||||
super(parent, type);
|
||||
this.change = change;
|
||||
addParameter(Parameter.PLAYER);
|
||||
addParameter(new Parameter("<attribute>",
|
||||
(explorer, list) -> MMOCore.plugin.skillManager.getAll().forEach(skill -> list.add(skill.getHandler().getId().toUpperCase()))));
|
||||
addParameter(Parameter.AMOUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandSender sender, String[] args) {
|
||||
if (args.length < 6)
|
||||
return CommandResult.THROW_USAGE;
|
||||
|
||||
Player player = Bukkit.getPlayer(args[3]);
|
||||
if (player == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
|
||||
RegisteredSkill skill = MMOCore.plugin.skillManager.getSkill(args[4]);
|
||||
if (skill == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Could not find the skill called " + args[4] + ".");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClassSkill classSkill=null;
|
||||
for(ClassSkill var:playerData.getProfess().getSkills()) {
|
||||
if(var.getSkill().equals(skill))
|
||||
classSkill=var;
|
||||
}
|
||||
|
||||
if(classSkill==null||classSkill.getUnlockLevel() > playerData.getLevel()) {
|
||||
sender.sendMessage(ChatColor.RED+ skill.getName()+" is not unlockable for "+player.getName()+".");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
|
||||
int amount;
|
||||
try {
|
||||
amount = Integer.parseInt(args[5]);
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(ChatColor.RED + args[5] + " is not a valid number.");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
int value = change.apply(playerData.getSkillLevel(skill), amount);
|
||||
playerData.setSkillLevel(skill, value);
|
||||
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + player.getName() + ChatColor.YELLOW
|
||||
+ " is now level " + ChatColor.GOLD + value + ChatColor.YELLOW + " for " + skill.getName() + ".");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandSender sender, String[] args) {
|
||||
return CommandResult.THROW_USAGE;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
|
||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
@ -14,6 +15,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
@ -46,6 +48,23 @@ public class SkillList extends EditableInventory {
|
||||
if (function.equals("upgrade"))
|
||||
return new UpgradeItem(config);
|
||||
|
||||
if (function.equals("reallocation")) {
|
||||
|
||||
return new InventoryItem(config) {
|
||||
|
||||
@Override
|
||||
public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
|
||||
Placeholders holders = new Placeholders();
|
||||
holders.register("skill_points", inv.getPlayerData().getSkillPoints());
|
||||
holders.register("points", inv.getPlayerData().getSkillReallocationPoints());
|
||||
holders.register("total", inv.getPlayerData().countSkillPointsWhenReallocate());
|
||||
return holders;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (function.equals("slot"))
|
||||
return new InventoryItem<SkillViewerInventory>(config) {
|
||||
private final String none = MythicLib.plugin.parseColors(config.getString("no-skill"));
|
||||
@ -70,6 +89,9 @@ public class SkillList extends EditableInventory {
|
||||
|
||||
@Override
|
||||
public ItemStack display(SkillViewerInventory inv, int n) {
|
||||
if (n >= inv.getPlayerData().getProfess().getMaxBoundSkills()) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
ItemStack item = super.display(inv, n);
|
||||
if (!inv.getPlayerData().hasSkillBound(n)) {
|
||||
item.setType(emptyMaterial);
|
||||
@ -225,27 +247,27 @@ public class SkillList extends EditableInventory {
|
||||
return new Placeholders();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class UpgradeItem extends InventoryItem<SkillViewerInventory> {
|
||||
private int shiftCost=1;
|
||||
|
||||
private int shiftCost = 1;
|
||||
|
||||
public UpgradeItem(ConfigurationSection config) {
|
||||
super(config);
|
||||
if(config.contains("shift-cost")) {
|
||||
if (config.contains("shift-cost")) {
|
||||
this.shiftCost = config.getInt("shift-cost");
|
||||
if (shiftCost < 1) {
|
||||
MMOCore.log(Level.WARNING, "Upgrade shift-cost cannot be less than 1. Using default value: 1");
|
||||
shiftCost = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
|
||||
RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill();
|
||||
Placeholders holders = new Placeholders();
|
||||
|
||||
|
||||
holders.register("skill_caps", selected.getName().toUpperCase());
|
||||
holders.register("skill", selected.getName());
|
||||
holders.register("skill_points", "" + inv.getPlayerData().getSkillPoints());
|
||||
@ -253,7 +275,7 @@ public class SkillList extends EditableInventory {
|
||||
return holders;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SkillViewerInventory extends GeneratedInventory {
|
||||
|
||||
// Cached information
|
||||
@ -305,6 +327,35 @@ public class SkillList extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
if(item.getFunction().equals("reallocation")) {
|
||||
|
||||
|
||||
|
||||
int spent= getPlayerData().countSkillPointsWhenReallocate();
|
||||
|
||||
if (spent < 1) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("no-skill-points-spent").send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerData.getSkillReallocationPoints() < 1) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-skill-reallocation-point").send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for(ClassSkill skill:playerData.getProfess().getSkills()) {
|
||||
playerData.setSkillLevel(skill.getSkill(), 1);
|
||||
}
|
||||
playerData.giveSkillPoints(spent);
|
||||
playerData.setSkillReallocationPoints(playerData.getSkillReallocationPoints()-1);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("skill-points-reallocated", "points", "" + playerData.getSkillPoints()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_SKILLS).playTo(getPlayer());
|
||||
open();
|
||||
}
|
||||
|
||||
if (item.getFunction().equals("previous")) {
|
||||
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
|
||||
page--;
|
||||
@ -325,15 +376,13 @@ public class SkillList extends EditableInventory {
|
||||
if (item.getFunction().equals("slot")) {
|
||||
int index = slotSlots.indexOf(context.getSlot());
|
||||
|
||||
|
||||
// unbind if there is a current spell.
|
||||
KEy // unbind if there is a current spell.
|
||||
if (context.getClickType() == ClickType.RIGHT) {
|
||||
if (!playerData.hasSkillBound(index)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
|
||||
playerData.unbindSkill(index);
|
||||
open();
|
||||
@ -349,6 +398,7 @@ public class SkillList extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!playerData.hasSkillUnlocked(selected)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
@ -367,7 +417,7 @@ public class SkillList extends EditableInventory {
|
||||
*/
|
||||
if (item.getFunction().equals("upgrade")) {
|
||||
int shiftCost = ((UpgradeItem) item).shiftCost;
|
||||
|
||||
|
||||
if (!playerData.hasSkillUnlocked(selected)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
@ -385,21 +435,21 @@ public class SkillList extends EditableInventory {
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (context.getClickType().isShiftClick()) {
|
||||
if (playerData.getSkillPoints() < shiftCost) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-enough-skill-points-shift", "shift_points", "" + shiftCost).send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
playerData.giveSkillPoints(-shiftCost);
|
||||
playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + shiftCost);
|
||||
} else {
|
||||
playerData.giveSkillPoints(-1);
|
||||
playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1);
|
||||
}
|
||||
|
||||
|
||||
MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level",
|
||||
"" + playerData.getSkillLevel(selected.getSkill())).send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
|
||||
|
@ -19,11 +19,11 @@ import java.util.logging.Level;
|
||||
public abstract class EditableInventory {
|
||||
private final String id;
|
||||
|
||||
private FileConfiguration config;
|
||||
private AdaptorType adaptorType;
|
||||
private String name;
|
||||
private int slots;
|
||||
|
||||
protected double radius, angleGap, verticalGap, curvature, verticalOffset, interactSensitivity;
|
||||
|
||||
/*
|
||||
* This set is linked so it keeps the order/priority in
|
||||
@ -39,17 +39,10 @@ public abstract class EditableInventory {
|
||||
}
|
||||
|
||||
public void reload(FileConfiguration config) {
|
||||
|
||||
this.config = config;
|
||||
this.adaptorType = AdaptorType.valueOf(UtilityMethods.enumName(config.getString("adaptor-type", "classic-adaptor")));
|
||||
Validate.notNull(adaptorType, config.getString("adaptor-type") + " does not correspond to an adaptor-type.");//TODO
|
||||
|
||||
this.radius = config.getDouble("radius", 2);
|
||||
this.angleGap = config.getDouble("angle-gap", 10);
|
||||
this.verticalGap = config.getDouble("vertical-gap", 1);
|
||||
this.curvature = config.getDouble("curvature", 1);
|
||||
this.verticalOffset = config.getDouble("vertical-offset", 0);
|
||||
this.interactSensitivity = config.getDouble("interact-sensitivity", 0.97);
|
||||
|
||||
this.name = config.getString("name");
|
||||
Validate.notNull(name, "Name must not be null");
|
||||
|
||||
@ -91,28 +84,9 @@ public abstract class EditableInventory {
|
||||
return adaptorType;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public double getAngleGap() {
|
||||
return angleGap;
|
||||
}
|
||||
|
||||
public double getVerticalGap() {
|
||||
return verticalGap;
|
||||
}
|
||||
|
||||
public double getInteractSensitivity() {
|
||||
return interactSensitivity;
|
||||
}
|
||||
|
||||
public double getCurvature() {
|
||||
return curvature;
|
||||
}
|
||||
|
||||
public double getVerticalOffset() {
|
||||
return verticalOffset;
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public InventoryItem getByFunction(String function) {
|
||||
|
@ -20,7 +20,6 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
public GeneratedInventory(PlayerData playerData, EditableInventory editable) {
|
||||
super(playerData);
|
||||
|
||||
this.editable = editable;
|
||||
this.adaptor = editable.getAdaptorType().supply(this);
|
||||
}
|
||||
@ -30,6 +29,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
}
|
||||
|
||||
public EditableInventory getEditable() {
|
||||
|
||||
return editable;
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
return ((ClassicAdaptor) adaptor).getInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
|
||||
/*
|
||||
* Very important, in order to prevent ghost items, the loaded items map
|
||||
* must be cleared when the inventory is updated or open at least twice
|
||||
@ -75,7 +75,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
/**
|
||||
* @deprecated Not a fan of that implementation.
|
||||
* Better work with {@link InventoryItem#setDisplayed(Inventory, GeneratedInventory)}
|
||||
* Better work with {@link InventoryItem#setDisplayed(Inventory, GeneratedInventory)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void dynamicallyUpdateItem(InventoryItem<?> item, int n, ItemStack placed, Consumer<ItemStack> update) {
|
||||
@ -83,6 +83,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClicked(InventoryClickContext context) {
|
||||
context.setCancelled(true);
|
||||
InventoryItem item = getBySlot(context.getSlot());
|
||||
|
@ -48,10 +48,13 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
|
||||
private final HashMap<ItemStack, ArmorStand> hiddenArmorStand = new HashMap<>();
|
||||
|
||||
protected double radius, angleGap, verticalGap, curvature, verticalOffset, interactSensitivity;
|
||||
|
||||
|
||||
private boolean firstTime = true;
|
||||
|
||||
private final Vector direction = generated.getPlayer().getEyeLocation().getDirection().setY(0);
|
||||
private final Location location = generated.getPlayer().getLocation().add(new Vector(0, generated.getEditable().getVerticalOffset(), 0));
|
||||
private final Location location;
|
||||
|
||||
//Zoomed=-1 no armorstand are under zoom
|
||||
private int zoomed = -1;
|
||||
@ -59,6 +62,14 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
|
||||
public ThreeDimAdaptor(GeneratedInventory generated) {
|
||||
super(generated);
|
||||
|
||||
this.radius = generated.getEditable().getConfig().getDouble("radius", 2);
|
||||
this.angleGap = generated.getEditable().getConfig().getDouble("angle-gap", 10);
|
||||
this.verticalGap = generated.getEditable().getConfig().getDouble("vertical-gap", 1);
|
||||
this.curvature = generated.getEditable().getConfig().getDouble("curvature", 1);
|
||||
this.verticalOffset = generated.getEditable().getConfig().getDouble("vertical-offset", 0);
|
||||
this.interactSensitivity = generated.getEditable().getConfig().getDouble("interact-sensitivity", 0.97);
|
||||
location = generated.getPlayer().getLocation().add(new Vector(0, verticalOffset, 0));
|
||||
}
|
||||
|
||||
|
||||
@ -180,9 +191,12 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
|
||||
private void setItem(ItemStack item, int n, double percentage) {
|
||||
Location location = getLocation(n, percentage);
|
||||
if(item.getType().toString().contains("SKULL")||item.getType().toString().contains("HEAD")) {
|
||||
location.add(new Vector(0,4.9,0));
|
||||
}
|
||||
//We create the armorStand corresponding to display the item
|
||||
ArmorStand armorStand = (ArmorStand) generated.getPlayer().getWorld().spawnEntity(location, EntityType.ARMOR_STAND);
|
||||
armorStand.setVisible(false);
|
||||
armorStand.setVisible(true);
|
||||
armorStand.setSmall(false);
|
||||
armorStand.setArms(true);
|
||||
armorStand.setGravity(false);
|
||||
@ -317,13 +331,13 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
|
||||
Location cloneLocation = location.clone();
|
||||
Vector cloneDirection = direction.clone().rotateAroundAxis(new Vector(0, 1, 0),
|
||||
-((n % 9) - 4) * generated.getEditable().getAngleGap() * Math.PI / 180);
|
||||
-((n % 9) - 4) * angleGap * Math.PI / 180);
|
||||
|
||||
//Curvature of 1: r=cst Curvature of 1: r=R/cos(angle) (a plane)
|
||||
double radius = percentage * generated.getEditable().getRadius() / Math.cos((1 - generated.getEditable().getCurvature())
|
||||
* -((n % 9) - 4) * generated.getEditable().getAngleGap() * Math.PI / 180);
|
||||
double radius = percentage * this.radius / Math.cos((1 - curvature)
|
||||
* -((n % 9) - 4) * angleGap * Math.PI / 180);
|
||||
cloneDirection = cloneDirection.normalize().multiply(radius);
|
||||
cloneDirection.add(new Vector(0, percentage * generated.getEditable().getVerticalGap() * ((generated.getEditable().getSlots() - n - 1) / 9), 1));
|
||||
cloneDirection.add(new Vector(0, percentage * verticalGap * ((generated.getEditable().getSlots() - n - 1) / 9), 1));
|
||||
//We get the final direction
|
||||
cloneLocation.add(cloneDirection);
|
||||
|
||||
@ -380,33 +394,36 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
if (!e.getFrom().getBlock().getLocation().equals(e.getTo().getBlock().getLocation()))
|
||||
ThreeDimAdaptor.this.close();
|
||||
else {
|
||||
//If the player no longer looks at the zoom as:
|
||||
if (zoomed != -1 && generated.getPlayer().getLocation().getDirection().normalize().dot(
|
||||
armorStands.get(zoomed).getLocation().add(new Vector(0, 0.25 * armorStands.get(zoomed).getHeight(), 0))
|
||||
.subtract(generated.getPlayer().getLocation()).toVector().normalize()) < generated.getEditable().getInteractSensitivity()) {
|
||||
armorStands.get(zoomed).teleport(getLocation(zoomed, 1));
|
||||
zoomed = -1;
|
||||
removeLore();
|
||||
int closest = -1;
|
||||
double closestScalar = 1;
|
||||
for (int n : armorStands.keySet()) {
|
||||
ArmorStand as = armorStands.get(n);
|
||||
Location asLocation = as.getLocation().add(new Vector(0, 0.25 * as.getHeight(), 0));
|
||||
|
||||
|
||||
double scalar = generated.getPlayer().getLocation().getDirection().normalize().dot(
|
||||
asLocation.subtract(generated.getPlayer().getLocation()).toVector().normalize());
|
||||
|
||||
if (scalar > interactSensitivity && scalar < closestScalar) {
|
||||
closestScalar = scalar;
|
||||
closest = n;
|
||||
}
|
||||
}
|
||||
if (zoomed == -1) {
|
||||
for (int n : armorStands.keySet()) {
|
||||
ArmorStand as = armorStands.get(n);
|
||||
Location asLocation = as.getLocation().add(new Vector(0, 0.25 * as.getHeight(), 0));
|
||||
|
||||
|
||||
double scalar = generated.getPlayer().getLocation().getDirection().normalize().dot(
|
||||
asLocation.subtract(generated.getPlayer().getLocation()).toVector().normalize());
|
||||
|
||||
if (scalar > generated.getEditable().getInteractSensitivity()) {
|
||||
as.teleport(getLocation(n, 0.75));
|
||||
zoomed = n;
|
||||
displayLore(zoomed);
|
||||
}
|
||||
|
||||
|
||||
if (closest != zoomed) {
|
||||
if (zoomed != -1) {
|
||||
removeLore();
|
||||
armorStands.get(zoomed).teleport(getLocation(zoomed, 1));
|
||||
}
|
||||
if (closest != -1) {
|
||||
armorStands.get(zoomed).teleport(getLocation(closest, 0.75));
|
||||
zoomed = closest;
|
||||
displayLore(closest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -416,7 +433,11 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
@EventHandler
|
||||
public void onInteract(PlayerInteractAtEntityEvent event) {
|
||||
if (event.getPlayer().equals(generated.getPlayer()))
|
||||
if (event.getRightClicked() instanceof ArmorStand armorStand) {
|
||||
if (event.getRightClicked() instanceof ArmorStand armorStand)
|
||||
event.setCancelled(true);
|
||||
|
||||
|
||||
/*
|
||||
if (armorStands.values().contains(armorStand)) {
|
||||
PersistentDataContainer container = armorStand.getPersistentDataContainer();
|
||||
int slot = container.get(new NamespacedKey(MMOCore.plugin, "slot"), PersistentDataType.INTEGER);
|
||||
@ -428,6 +449,7 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
generated.whenClicked(new InventoryClickContext(slot, armorStand.getEquipment().getItem(EquipmentSlot.HEAD), clickType, event));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -465,35 +487,40 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(EntityDamageByEntityEvent event) {
|
||||
|
||||
if (event.getDamager() instanceof Player player) {
|
||||
if (event.getDamager() instanceof Player player)
|
||||
if (player.equals(generated.getPlayer()))
|
||||
if (event.getEntity() instanceof ArmorStand armorStand) {
|
||||
if (armorStands.values().contains(armorStand)) {
|
||||
PersistentDataContainer container = armorStand.getPersistentDataContainer();
|
||||
int slot = container.get(new NamespacedKey(MMOCore.plugin, "slot"), PersistentDataType.INTEGER);
|
||||
ClickType clickType;
|
||||
if (player.isSneaking())
|
||||
clickType = ClickType.SHIFT_LEFT;
|
||||
else
|
||||
clickType = ClickType.LEFT;
|
||||
|
||||
ItemStack itemStack = armorStand.getEquipment().getItem(EquipmentSlot.HEAD);
|
||||
generated.whenClicked(new InventoryClickContext(slot, itemStack, clickType, event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getEntity() instanceof ArmorStand armorStand)
|
||||
if (armorStands.values().contains(armorStand))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
PersistentDataContainer container = armorStand.getPersistentDataContainer();
|
||||
int slot = container.get(new NamespacedKey(MMOCore.plugin, "slot"), PersistentDataType.INTEGER);
|
||||
ClickType clickType;
|
||||
if(player.isSneaking())
|
||||
clickType =ClickType.SHIFT_LEFT;
|
||||
else
|
||||
clickType =ClickType.LEFT;
|
||||
|
||||
ItemStack itemStack = armorStand.getEquipment().getItem(EquipmentSlot.HEAD);
|
||||
generated.whenClicked(new
|
||||
|
||||
InventoryClickContext(slot, itemStack, clickType, event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@Override
|
||||
public void whenClosed() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
/**
|
||||
* This registers all the KeyPress events. All events are registered
|
||||
@ -32,7 +33,7 @@ public class PlayerPressKeyListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void registerClickKey(PlayerInteractEvent event) {
|
||||
if (event.useItemInHand() != Event.Result.DENY && event.getAction().name().contains("CLICK")) {
|
||||
if (event.useItemInHand() != Event.Result.DENY && event.getAction().name().contains("CLICK")&&event.getHand().equals(EquipmentSlot.HAND)) {
|
||||
boolean rightClick = event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK;
|
||||
PlayerKeyPressEvent called = new PlayerKeyPressEvent(PlayerData.get(event.getPlayer()), rightClick ? PlayerKey.RIGHT_CLICK : PlayerKey.LEFT_CLICK, event);
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
|
@ -28,7 +28,7 @@ public class ConfigManager {
|
||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||
public double lootChestsChanceWeight, fishingDropsChanceWeight;
|
||||
public int maxPartyLevelDifference;
|
||||
public int maxPartyLevelDifference,maxBoundSkills;
|
||||
|
||||
private final FileConfiguration messages;
|
||||
|
||||
@ -116,6 +116,7 @@ public class ConfigManager {
|
||||
canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast");
|
||||
cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp");
|
||||
saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info");
|
||||
maxBoundSkills= MMOCore.plugin.getConfig().getInt("max-bound-skills",6);
|
||||
}
|
||||
|
||||
private ChatColor getColorOrDefault(String key, ChatColor defaultColor) {
|
||||
|
@ -26,6 +26,7 @@ public class SkillManager implements MMOCoreManager {
|
||||
skills.put(skill.getHandler().getId().toUpperCase(), skill);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public RegisteredSkill getSkill(String id) {
|
||||
return skills.get(id.toUpperCase());
|
||||
|
@ -16,7 +16,7 @@ import java.util.*;
|
||||
public abstract class PlayerDataManager {
|
||||
private final static Map<UUID, PlayerData> data = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private DefaultPlayerData defaultData = new DefaultPlayerData(1, 0, 0, 0, 0);
|
||||
private DefaultPlayerData defaultData = new DefaultPlayerData(1, 0, 0, 0, 0,0);
|
||||
|
||||
public PlayerData get(OfflinePlayer player) {
|
||||
return get(player.getUniqueId());
|
||||
@ -134,7 +134,7 @@ public abstract class PlayerDataManager {
|
||||
public abstract void saveData(PlayerData data);
|
||||
|
||||
public class DefaultPlayerData {
|
||||
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints;
|
||||
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints,skillReallocPoints;
|
||||
|
||||
public DefaultPlayerData(ConfigurationSection config) {
|
||||
level = config.getInt("level", 1);
|
||||
@ -142,14 +142,17 @@ public abstract class PlayerDataManager {
|
||||
skillPoints = config.getInt("skill-points");
|
||||
attributePoints = config.getInt("attribute-points");
|
||||
attrReallocPoints = config.getInt("attribute-realloc-points");
|
||||
skillReallocPoints=config.getInt("skill-realloc-points",0);
|
||||
}
|
||||
|
||||
public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints) {
|
||||
public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints,int skillReallocPoints) {
|
||||
this.level = level;
|
||||
this.classPoints = classPoints;
|
||||
this.skillPoints = skillPoints;
|
||||
this.attributePoints = attributePoints;
|
||||
this.attrReallocPoints = attrReallocPoints;
|
||||
this.skillReallocPoints=skillReallocPoints;
|
||||
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
@ -172,6 +175,10 @@ public abstract class PlayerDataManager {
|
||||
return attributePoints;
|
||||
}
|
||||
|
||||
public int getSkillReallocPoints() {
|
||||
return skillReallocPoints;
|
||||
}
|
||||
|
||||
public void apply(PlayerData player) {
|
||||
player.setLevel(level);
|
||||
player.setClassPoints(classPoints);
|
||||
|
@ -35,6 +35,11 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//To prevent infinite loops
|
||||
if (System.currentTimeMillis() - startTime > 4000) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + data.getUniqueId() + "';", (result) -> {
|
||||
try {
|
||||
@ -55,6 +60,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
|
||||
data.setClassPoints(result.getInt("class_points"));
|
||||
data.setSkillPoints(result.getInt("skill_points"));
|
||||
data.setSkillReallocationPoints(result.getInt("skill_reallocation_points"));
|
||||
data.setAttributePoints(result.getInt("attribute_points"));
|
||||
data.setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
|
||||
data.setLevel(result.getInt("level"));
|
||||
@ -121,6 +127,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
data.setLevel(getDefaultData().getLevel());
|
||||
data.setClassPoints(getDefaultData().getClassPoints());
|
||||
data.setSkillPoints(getDefaultData().getSkillPoints());
|
||||
data.setSkillReallocationPoints(getDefaultData().getSkillReallocPoints());
|
||||
data.setAttributePoints(getDefaultData().getAttributePoints());
|
||||
data.setAttributeReallocationPoints(getDefaultData().getAttrReallocPoints());
|
||||
data.setExperience(0);
|
||||
@ -145,11 +152,12 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
@Override
|
||||
public void saveData(PlayerData data) {
|
||||
|
||||
MySQLTableEditor sql = new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(),provider);
|
||||
MySQLTableEditor sql = new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(), provider);
|
||||
MMOCore.sqlDebug("Saving data for: '" + data.getUniqueId() + "'...");
|
||||
|
||||
sql.updateData("class_points", data.getClassPoints());
|
||||
sql.updateData("skill_points", data.getSkillPoints());
|
||||
sql.updateData("skill_reallocation_points",data.getSkillReallocationPoints());
|
||||
sql.updateData("attribute_points", data.getAttributePoints());
|
||||
sql.updateData("attribute_realloc_points", data.getAttributeReallocationPoints());
|
||||
sql.updateData("level", data.getLevel());
|
||||
|
@ -30,6 +30,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
|
||||
data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
|
||||
data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
|
||||
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points",getDefaultData().getSkillReallocPoints()));
|
||||
data.setAttributePoints(config.getInt("attribute-points", getDefaultData().getAttributePoints()));
|
||||
data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttrReallocPoints()));
|
||||
data.setLevel(config.getInt("level", getDefaultData().getLevel()));
|
||||
@ -90,6 +91,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
|
||||
config.set("class-points", data.getClassPoints());
|
||||
config.set("skill-points", data.getSkillPoints());
|
||||
config.set("skill-reallocation-points",data.getSkillReallocationPoints());
|
||||
config.set("attribute-points", data.getAttributePoints());
|
||||
// config.set("skill-realloc-points", skillReallocationPoints);
|
||||
config.set("attribute-realloc-points", data.getAttributeReallocationPoints());
|
||||
|
@ -49,13 +49,6 @@ public class KeyCombos implements Listener {
|
||||
@Nullable
|
||||
private final SoundObject beginComboSound, comboClickSound, failComboSound;
|
||||
|
||||
/**
|
||||
* Essentially the inverse of the {@link #combos} map. This maps
|
||||
* the skill slot to the corresponding key combo. There's no problem
|
||||
* because the maps are 100% bijective
|
||||
*/
|
||||
private static final Map<Integer, KeyCombo> PUBLIC_COMBOS = new HashMap<>();
|
||||
|
||||
public KeyCombos(ConfigurationSection config) {
|
||||
|
||||
int longestCombo = 0;
|
||||
@ -72,8 +65,6 @@ public class KeyCombos implements Listener {
|
||||
|
||||
combos.put(combo, spellSlot);
|
||||
longestCombo = Math.max(longestCombo, combo.countKeys());
|
||||
|
||||
PUBLIC_COMBOS.put(spellSlot, combo);
|
||||
} catch (RuntimeException exception) {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load key combo '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
@ -112,6 +103,7 @@ public class KeyCombos implements Listener {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Adding pressed key
|
||||
CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting();
|
||||
casting.current.registerKey(event.getPressed());
|
||||
@ -123,8 +115,8 @@ public class KeyCombos implements Listener {
|
||||
event.setCancelled(true);
|
||||
|
||||
// Hash current combo and check
|
||||
if (combos.containsKey(casting.current)) {
|
||||
int spellSlot = combos.get(casting.current) - 1;
|
||||
if (casting.classCombos.containsKey(casting.current)) {
|
||||
int spellSlot = casting.classCombos.get(casting.current) - 1;
|
||||
playerData.leaveCastingMode();
|
||||
|
||||
// Cast spell
|
||||
@ -136,7 +128,7 @@ public class KeyCombos implements Listener {
|
||||
}
|
||||
|
||||
// Check if current combo is too large
|
||||
if (casting.current.countKeys() >= longestCombo) {
|
||||
if (casting.current.countKeys() >= casting.classLongestCombo) {
|
||||
playerData.leaveCastingMode();
|
||||
if (failComboSound != null)
|
||||
failComboSound.playTo(player);
|
||||
@ -167,20 +159,36 @@ public class KeyCombos implements Listener {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the player current combos & the combos applicable to the player (combos defined in its class or the default combos of the config.yml)
|
||||
*/
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
private final KeyCombo current = new KeyCombo();
|
||||
//Combos used: default combos from the config or the combos defined in the player class.
|
||||
private final Map<KeyCombo, Integer> classCombos;
|
||||
private int classLongestCombo;
|
||||
|
||||
CustomSkillCastingHandler(PlayerData caster) {
|
||||
super(caster, 10);
|
||||
if (!caster.getProfess().getKeyCombos().isEmpty()) {
|
||||
classCombos=caster.getProfess().getKeyCombos();
|
||||
classLongestCombo=caster.getProfess().getLongestCombo();
|
||||
} else {
|
||||
classCombos = combos;
|
||||
classLongestCombo=longestCombo;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (actionBarOptions != null)
|
||||
getCaster().displayActionBar(actionBarOptions.format(current));
|
||||
getCaster().displayActionBar(actionBarOptions.format(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class ActionBarOptions {
|
||||
private final String separator, noKey;
|
||||
|
||||
@ -198,18 +206,19 @@ public class KeyCombos implements Listener {
|
||||
keyNames.put(key, Objects.requireNonNull(config.getString("key-name." + key.name()), "Could not find translation for key " + key.name()));
|
||||
}
|
||||
|
||||
public String format(KeyCombo currentCombo) {
|
||||
public String format(CustomSkillCastingHandler casting) {
|
||||
|
||||
// Join all keys with separator
|
||||
String builder = currentCombo.countKeys() == 0 ? noKey : keyNames.get(currentCombo.getAt(0));
|
||||
String builder = casting.current.countKeys() == 0 ? noKey : keyNames.get(casting.current.getAt(0));
|
||||
int j = 1;
|
||||
for (; j < currentCombo.countKeys(); j++)
|
||||
builder += separator + keyNames.get(currentCombo.getAt(j));
|
||||
for (; j < casting.current.countKeys(); j++)
|
||||
builder += separator + keyNames.get(casting.current.getAt(j));
|
||||
|
||||
// All remaining
|
||||
for (; j < longestCombo; j++)
|
||||
for (; j < casting.classLongestCombo; j++)
|
||||
builder += separator + noKey;
|
||||
|
||||
|
||||
return MythicLib.plugin.parseColors(builder);
|
||||
}
|
||||
}
|
||||
|
@ -17,124 +17,131 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class SkillBar implements Listener {
|
||||
private final PlayerKey mainKey;
|
||||
private final PlayerKey mainKey;
|
||||
|
||||
public SkillBar(ConfigurationSection config) {
|
||||
mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key")));
|
||||
}
|
||||
public SkillBar(ConfigurationSection config) {
|
||||
mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key")));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void a(PlayerKeyPressEvent event) {
|
||||
if (event.getPressed() != mainKey) return;
|
||||
@EventHandler
|
||||
public void a(PlayerKeyPressEvent event) {
|
||||
if (event.getPressed() != mainKey) return;
|
||||
|
||||
// Always cancel event
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
// Always cancel event
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Enter spell casting
|
||||
Player player = event.getData().getPlayer();
|
||||
PlayerData playerData = event.getData();
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills()
|
||||
.isEmpty()) {
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
||||
}
|
||||
}
|
||||
// Enter spell casting
|
||||
Player player = event.getData().getPlayer();
|
||||
PlayerData playerData = event.getData();
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills()
|
||||
.isEmpty()) {
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
private final String ready = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.ready").message();
|
||||
private final String onCooldown = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.on-cooldown").message();
|
||||
private final String noMana = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.no-mana").message();
|
||||
private final String noStamina = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.no-stamina").message();
|
||||
private final String split = MMOCore.plugin.configManager.getSimpleMessage("casting.split").message();
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
private final String ready = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.ready").message();
|
||||
private final String onCooldown = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.on-cooldown").message();
|
||||
private final String noMana = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.no-mana").message();
|
||||
private final String noStamina = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.no-stamina").message();
|
||||
private final String split = MMOCore.plugin.configManager.getSimpleMessage("casting.split").message();
|
||||
|
||||
private int j;
|
||||
private int j;
|
||||
|
||||
CustomSkillCastingHandler(PlayerData playerData) {
|
||||
super(playerData, 1);
|
||||
}
|
||||
CustomSkillCastingHandler(PlayerData playerData) {
|
||||
super(playerData, 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSkillCast(PlayerItemHeldEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (!getCaster().isOnline()) return;
|
||||
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
||||
@EventHandler
|
||||
public void onSkillCast(PlayerItemHeldEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (!getCaster().isOnline()) return;
|
||||
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
||||
|
||||
/*
|
||||
* When the event is cancelled, another playerItemHeldEvent is
|
||||
* called and previous and next slots are equal. the event must not
|
||||
* listen to that non-player called event.
|
||||
*/
|
||||
if (event.getPreviousSlot() == event.getNewSlot()) return;
|
||||
/*
|
||||
* When the event is cancelled, another playerItemHeldEvent is
|
||||
* called and previous and next slots are equal. the event must not
|
||||
* listen to that non-player called event.
|
||||
*/
|
||||
if (event.getPreviousSlot() == event.getNewSlot()) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
|
||||
event.setCancelled(true);
|
||||
int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
|
||||
|
||||
/*
|
||||
* The event is called again soon after the first since when
|
||||
* cancelling the first one, the player held item slot must go back
|
||||
* to the previous one.
|
||||
*/
|
||||
if (slot >= 0 && getCaster().hasSkillBound(slot)) {
|
||||
PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
|
||||
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The event is called again soon after the first since when
|
||||
* cancelling the first one, the player held item slot must go back
|
||||
* to the previous one.
|
||||
*/
|
||||
if (slot >= 0 && getCaster().hasSkillBound(slot)) {
|
||||
PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
|
||||
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void stopCasting(PlayerKeyPressEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPressed() == mainKey && event.getPlayer().equals(getCaster().getPlayer())) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_END).playTo(player);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("casting.no-longer").send(getCaster().getPlayer());
|
||||
PlayerData.get(player).leaveCastingMode();
|
||||
}
|
||||
}
|
||||
@EventHandler
|
||||
public void stopCasting(PlayerKeyPressEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPressed() == mainKey && event.getPlayer().equals(getCaster().getPlayer())) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_END).playTo(player);
|
||||
|
||||
private String getFormat(PlayerData data) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (!data.isOnline()) return str.toString();
|
||||
for (int j = 0; j < data.getBoundSkills().size(); j++) {
|
||||
ClassSkill skill = data.getBoundSkill(j);
|
||||
str.append((str.length() == 0) ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
|
||||
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
|
||||
data, skill) ? noStamina : ready)).replace("{index}",
|
||||
"" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0)))
|
||||
.replace("{skill}", data.getBoundSkill(j).getSkill().getName()));
|
||||
}
|
||||
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(),str.toString());
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("casting.no-longer").send(getCaster().getPlayer());
|
||||
}
|
||||
}.runTask(MMOCore.plugin);
|
||||
PlayerData.get(player).leaveCastingMode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't even need to check if the skill has the 'cooldown'
|
||||
* modifier. We just look for an entry in the cooldown map which
|
||||
* won't be here if the skill has no cooldown.
|
||||
*/
|
||||
private boolean onCooldown(PlayerData data, ClassSkill skill) {
|
||||
return data.getCooldownMap().isOnCooldown(skill);
|
||||
}
|
||||
private String getFormat(PlayerData data) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (!data.isOnline()) return str.toString();
|
||||
for (int j = 0; j < data.getBoundSkills().size(); j++) {
|
||||
ClassSkill skill = data.getBoundSkill(j);
|
||||
str.append((str.length() == 0) ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
|
||||
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
|
||||
data, skill) ? noStamina : ready)).replace("{index}",
|
||||
"" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0)))
|
||||
.replace("{skill}", data.getBoundSkill(j).getSkill().getName()));
|
||||
}
|
||||
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());
|
||||
}
|
||||
|
||||
private boolean noMana(PlayerData data, ClassSkill skill) {
|
||||
return skill.getSkill().hasModifier("mana") && skill.getModifier("mana", data.getSkillLevel(skill.getSkill())) > data.getMana();
|
||||
}
|
||||
/**
|
||||
* We don't even need to check if the skill has the 'cooldown'
|
||||
* modifier. We just look for an entry in the cooldown map which
|
||||
* won't be here if the skill has no cooldown.
|
||||
*/
|
||||
private boolean onCooldown(PlayerData data, ClassSkill skill) {
|
||||
return data.getCooldownMap().isOnCooldown(skill);
|
||||
}
|
||||
|
||||
private boolean noStamina(PlayerData data, ClassSkill skill) {
|
||||
return skill.getSkill().hasModifier("stamina") && skill.getModifier("stamina",
|
||||
data.getSkillLevel(skill.getSkill())) > data.getStamina();
|
||||
}
|
||||
private boolean noMana(PlayerData data, ClassSkill skill) {
|
||||
return skill.getSkill().hasModifier("mana") && skill.getModifier("mana", data.getSkillLevel(skill.getSkill())) > data.getMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (j % 20 == 0) getCaster().displayActionBar(getFormat(getCaster()));
|
||||
private boolean noStamina(PlayerData data, ClassSkill skill) {
|
||||
return skill.getSkill().hasModifier("stamina") && skill.getModifier("stamina",
|
||||
data.getSkillLevel(skill.getSkill())) > data.getStamina();
|
||||
}
|
||||
|
||||
for (int k = 0; k < 2; k++) {
|
||||
double a = (double) j++ / 5;
|
||||
getCaster().getProfess().getCastParticle()
|
||||
.display(getCaster().getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (j % 20 == 0) getCaster().displayActionBar(getFormat(getCaster()));
|
||||
|
||||
for (int k = 0; k < 2; k++) {
|
||||
double a = (double) j++ / 5;
|
||||
getCaster().getProfess().getCastParticle()
|
||||
.display(getCaster().getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,11 @@ default-playerdata:
|
||||
level: 1
|
||||
class-points: 0
|
||||
skill-points: 0
|
||||
skill-realloc-points: 0
|
||||
attribute-points: 0
|
||||
attribute-realloc-points: 0
|
||||
|
||||
|
||||
# The list of all conditions which must be met for the
|
||||
# BLOCK REGEN and BLOCK RESTRICTIONS to apply. Set to
|
||||
# 'custom-mine-conditions: []' to disable custom mining entirely.
|
||||
@ -89,6 +91,7 @@ skill-casting:
|
||||
mode: SKILL_BAR
|
||||
open: SWAP_HANDS
|
||||
|
||||
|
||||
loot-chests:
|
||||
|
||||
# Time in seconds it takes for a loot chest to
|
||||
@ -241,6 +244,7 @@ resource-bar-colors:
|
||||
# false - Never verbose
|
||||
command-verbose:
|
||||
attribute: true
|
||||
skill: true
|
||||
class: true
|
||||
experience: true
|
||||
level: true
|
||||
|
@ -100,6 +100,11 @@ skills:
|
||||
level: 15
|
||||
max-level: 30
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 6
|
||||
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -20,6 +20,9 @@ options:
|
||||
# Must match an existing exp curve filename from the 'expcurves' folder
|
||||
exp-curve: levels
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 5
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -54,6 +54,8 @@ mana:
|
||||
cast-particle:
|
||||
particle: SPELL_INSTANT
|
||||
|
||||
|
||||
|
||||
# Special resource regeneration: (when out of combat),
|
||||
# players can regen a set % of their maximum mana/missing mana.
|
||||
# This % can scale with the player level.
|
||||
@ -140,6 +142,11 @@ skills:
|
||||
level: 15
|
||||
max-level: 30
|
||||
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 6
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -33,6 +33,8 @@ max-level: 100
|
||||
|
||||
exp-table: class_exp_table
|
||||
|
||||
|
||||
|
||||
# Particles displayed around the player
|
||||
# when he enters the casting mode.
|
||||
cast-particle:
|
||||
@ -85,6 +87,11 @@ attributes:
|
||||
base: .105
|
||||
per-level: 0
|
||||
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 5
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -30,6 +30,8 @@ display:
|
||||
# Must match an existing exp curve filename from the 'expcurves' folder
|
||||
exp-curve: levels
|
||||
|
||||
|
||||
|
||||
# The maximum level players can reach
|
||||
max-level: 100
|
||||
|
||||
@ -75,6 +77,11 @@ attributes:
|
||||
base: .095
|
||||
per-level: 0
|
||||
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 5
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -33,6 +33,7 @@ max-level: 100
|
||||
|
||||
exp-table: class_exp_table
|
||||
|
||||
|
||||
options:
|
||||
# Mana and health regen only applies when out of combat
|
||||
off-combat-mana-regen: true
|
||||
@ -80,6 +81,10 @@ attributes:
|
||||
base: .105
|
||||
per-level: 0
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 5
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -116,6 +116,11 @@ attributes:
|
||||
base: 4.2
|
||||
per-level: 0.05
|
||||
|
||||
|
||||
|
||||
#The number of skills a player can bound.
|
||||
max-bound-skills: 5
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
|
@ -2,6 +2,7 @@
|
||||
# GUI display name
|
||||
name: Player Attributes
|
||||
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
@ -11,70 +12,61 @@ items:
|
||||
slots: [26]
|
||||
function: reallocation
|
||||
item: CAULDRON
|
||||
name: '&aReallocate Skill Points'
|
||||
name: '&aAttribute Points'
|
||||
lore:
|
||||
- ''
|
||||
- 'You have spent a total of &6{total}&7 skill points.'
|
||||
- '&7Right click to reallocate them.'
|
||||
- ''
|
||||
- '&eCosts 1 attribute reallocation point.'
|
||||
- '&e◆ Attribute Reallocation Points: &6{points}'
|
||||
- ''
|
||||
- 'You have spent a total of &6{total}&7 attribute points.'
|
||||
- '&7Right click to reallocate them.'
|
||||
- ''
|
||||
- '&eCosts 1 attribute reallocation point.'
|
||||
- '&e◆ Attribute Reallocation Points: &6{points}'
|
||||
str:
|
||||
slots: [11]
|
||||
function: attribute_strength
|
||||
shift-cost: 10
|
||||
name: '&a{name}'
|
||||
item: GOLDEN_APPLE
|
||||
lore: # {buffs} returns amount of buffs
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
|
||||
- '&7 +{buff_max_health}% Max Health (&a+{total_max_health}%&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&eShift-Click to level up for {shift_points} attribute points.'
|
||||
- ''
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
|
||||
- '&7 +{buff_max_health} Max Health (&a+{total_max_health}&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
dex:
|
||||
slots: [13]
|
||||
function: attribute_dexterity
|
||||
shift-cost: 10
|
||||
name: '&a{name}'
|
||||
item: LEATHER_BOOTS
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)'
|
||||
- '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)'
|
||||
- '&7 +{buff_attack_speed}% Attack Speed (&a+{total_attack_speed}&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&eShift-Click to level up for {shift_points} attribute points.'
|
||||
- ''
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)'
|
||||
- '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)'
|
||||
- '&7 +{buff_attack_speed} Attack Speed (&a+{total_attack_speed}&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
int:
|
||||
slots: [15]
|
||||
function: attribute_intelligence
|
||||
shift-cost: 10
|
||||
name: '&a{name}'
|
||||
item: BOOK
|
||||
lore:
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_magic_damage}% Magic Damage (&a+{total_magic_damage}%&7)'
|
||||
- '&7 +{buff_cooldown_reduction}% Cooldown Reduction (&a+{total_cooldown_reduction}%&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&eShift-Click to level up for {shift_points} attribute points.'
|
||||
- ''
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_magic_damage}% Magic Damage (&a+{total_magic_damage}%&7)'
|
||||
- '&7 +{buff_cooldown_reduction}% Cooldown Reduction (&a+{total_cooldown_reduction}%&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
|
@ -33,6 +33,18 @@ items:
|
||||
name: '&aPrevious'
|
||||
lore: { }
|
||||
|
||||
reallocate:
|
||||
slots: [26]
|
||||
function: reallocation
|
||||
item: CAULDRON
|
||||
name: '&aReallocate Skill Points'
|
||||
lore:
|
||||
- ''
|
||||
- 'You have spent a total of &6{total}&7 skill points.'
|
||||
- '&7Right click to reallocate them.'
|
||||
- ''
|
||||
- '&eCosts 1 skill reallocation point.'
|
||||
- '&e◆ Skill Reallocation Points: &6{points}'
|
||||
|
||||
#switch:
|
||||
#
|
||||
@ -87,11 +99,9 @@ items:
|
||||
upgrade:
|
||||
slots: [ 15 ]
|
||||
function: upgrade
|
||||
shift-cost: 10
|
||||
item: GREEN_STAINED_GLASS_PANE
|
||||
name: '&a&lUPGRADE {skill_caps}'
|
||||
lore:
|
||||
- '&7Costs 1 skill point.'
|
||||
- '&7Shift-Click to spend {shift_points} points'
|
||||
- ''
|
||||
- '&eCurrent Skill Points: {skill_points}'
|
||||
|
@ -157,7 +157,7 @@ no-permission-for-class:
|
||||
# Attributes
|
||||
no-attribute-points-spent: '&cYou have not spent any attribute points.'
|
||||
not-attribute-reallocation-point: '&cYou do not have 1 reallocation point.'
|
||||
not-attribute-point: '&cYou don''t have 1 attribute point.'
|
||||
not-attribute-point: '&cYou have no attribute point.'
|
||||
not-attribute-point-shift: '&cYou must have &4{shift_points} &cattribute points.'
|
||||
attribute-points-reallocated: '&eYou successfully reset your attributes. You now have &6{points} &eattribute points.'
|
||||
attribute-max-points-hit: '&cYou cannot level up this attribute anymore.'
|
||||
@ -173,8 +173,11 @@ no-skill-bound: '&cYou don''t have any skill bound to this slot.'
|
||||
not-active-skill: '&cThis is not an active skill.'
|
||||
skill-max-level-hit: '&cYou already hit the max level for that skill.'
|
||||
no-skill-placeholder: 'No Skill Bound'
|
||||
not-skill-reallocation-point: '&cYou do not have 1 skill reallocation point.'
|
||||
no-skill-points-spent: '&cYou have not spent any skill points.'
|
||||
skill-points-reallocated: '&eYou successfully reset your attributes. You now have &6{points} &eskill points.'
|
||||
|
||||
#Skill Tree
|
||||
# Skill Trees
|
||||
no-skill-tree-points-spent: '&cYou have not spent any skill tree points.'
|
||||
locked-node: '&cThis skill is locked!'
|
||||
upgrade-skill-node: '&eYour skill node &6{skill-node} &eis now Level &6{level}&e!'
|
||||
|
@ -19,6 +19,7 @@ select-class: UI_TOAST_CHALLENGE_COMPLETE
|
||||
|
||||
level-attribute: ENTITY_PLAYER_LEVELUP
|
||||
reset-attributes: ENTITY_PLAYER_LEVELUP
|
||||
reset-skills: ENTITY_PLAYER_LEVELUP
|
||||
|
||||
level-skill-tree-node: ENTITY_PLAYER_LEVELUP
|
||||
reset-skill-tree: ENTITY_PLAYER_LEVELUP
|
||||
|
Loading…
Reference in New Issue
Block a user