Debug + max-bound-skills+mmocore admin skill give...

This commit is contained in:
Ka0rX 2022-08-07 21:56:40 +02:00
parent 4d08a98ed2
commit a61b9bc634
18 changed files with 298 additions and 140 deletions

View File

@ -849,7 +849,10 @@ 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);

View File

@ -49,7 +49,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final int maxLevel, displayOrder;
private final ExpCurve expCurve;
private final ExperienceTable expTable;
private final int maxBoundSkills;
private final Map<String, LinearValue> stats = new HashMap<>();
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
private final List<Subclass> subclasses = new ArrayList<>();
@ -100,7 +100,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 {
@ -206,7 +206,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));
}
@ -262,6 +262,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");

View File

@ -49,6 +49,7 @@ public class CommandVerbose {
public enum CommandType {
ATTRIBUTE,
SKILL,
CLASS,
EXPERIENCE,
LEVEL,

View File

@ -6,32 +6,32 @@ 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 ExperienceCommandTreeNode(this));
addChild(new LevelCommandTreeNode(this));
addChild(new AttributeCommandTreeNode(this));
for (PlayerResource res : PlayerResource.values())
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
}
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 SkillCommandTreeNode(this));
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;
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
return CommandResult.THROW_USAGE;
}
}

View File

@ -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;
}
}

View File

@ -70,6 +70,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 +228,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 +256,7 @@ public class SkillList extends EditableInventory {
return holders;
}
}
public class SkillViewerInventory extends GeneratedInventory {
// Cached information
@ -367,7 +370,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 +388,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);

View File

@ -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;
@ -113,6 +113,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) {

View File

@ -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());

View File

@ -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 {
@ -145,7 +150,7 @@ 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());

View File

@ -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)));
}
}
}
}

View File

@ -89,6 +89,7 @@ skill-casting:
mode: SKILL_BAR
open: SWAP_HANDS
loot-chests:
# Time in seconds it takes for a loot chest to
@ -246,6 +247,7 @@ resource-bar-colors:
# false - Never verbose
command-verbose:
attribute: true
skill: true
class: true
experience: true
level: true

View File

@ -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}'

View File

@ -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}'

View File

@ -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}'

View File

@ -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}'

View File

@ -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}'

View File

@ -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}'

View File

@ -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}'