2013-03-01 06:52:01 +01:00
|
|
|
package com.gmail.nossr50.commands.skills;
|
|
|
|
|
|
|
|
import com.gmail.nossr50.config.AdvancedConfig;
|
mcMMO - Now with 100% more scoreboards!
mcMMO now allows for the use of scoreboards to display information in
several instances. By default, all scoreboards are enabled in the config,
and will only display for 10 seconds. After 10 seconds, the scoreboard
will go away and revert to the previously displayed scoreboard, if one
exists.
A global scoreboard now exists for tracking all player stats, and will be
displayed when /mctop is used. Your name will be highlighted in gold when
looking through the scoreboard. Additionally, the scoreboard will display
players in groups of 15, rather than groups of 10 like in chat.
Unfortunately, due to the limitations of scoreboards, the player's rank
will not be displayed in front of their name.
The scoreboard area is now also used for displaying data for /mcrank,
/inspect. and /mcstats. Due to the way scoreboards are handled, the power
level is not guarenteed to show up at any given location in the
scoreboard, but is instead displayed in gold so that it can be easily
found.
Lastly, the scoreboard area is also now used for displaying current data
on skills when the relevant /<skillname> command is used. The effects and
ability stats will still be shown in chat, but the current level, xp, and
remaining xp will be shown in the scoreboard.
2013-04-14 05:16:25 +02:00
|
|
|
import com.gmail.nossr50.config.Config;
|
2013-03-12 21:25:42 +01:00
|
|
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
2019-01-15 07:11:58 +01:00
|
|
|
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
2019-01-09 04:52:52 +01:00
|
|
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.locale.LocaleLoader;
|
2019-01-13 07:41:06 +01:00
|
|
|
import com.gmail.nossr50.skills.child.FamilyTree;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.util.Permissions;
|
|
|
|
import com.gmail.nossr50.util.StringUtils;
|
2019-01-15 07:11:58 +01:00
|
|
|
import com.gmail.nossr50.util.TextComponentFactory;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.util.commands.CommandUtils;
|
|
|
|
import com.gmail.nossr50.util.player.UserManager;
|
mcMMO - Now with 100% more scoreboards!
mcMMO now allows for the use of scoreboards to display information in
several instances. By default, all scoreboards are enabled in the config,
and will only display for 10 seconds. After 10 seconds, the scoreboard
will go away and revert to the previously displayed scoreboard, if one
exists.
A global scoreboard now exists for tracking all player stats, and will be
displayed when /mctop is used. Your name will be highlighted in gold when
looking through the scoreboard. Additionally, the scoreboard will display
players in groups of 15, rather than groups of 10 like in chat.
Unfortunately, due to the limitations of scoreboards, the player's rank
will not be displayed in front of their name.
The scoreboard area is now also used for displaying data for /mcrank,
/inspect. and /mcstats. Due to the way scoreboards are handled, the power
level is not guarenteed to show up at any given location in the
scoreboard, but is instead displayed in gold so that it can be easily
found.
Lastly, the scoreboard area is also now used for displaying current data
on skills when the relevant /<skillname> command is used. The effects and
ability stats will still be shown in chat, but the current level, xp, and
remaining xp will be shown in the scoreboard.
2013-04-14 05:16:25 +02:00
|
|
|
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.util.skills.PerksUtils;
|
2019-01-15 12:16:21 +01:00
|
|
|
import com.gmail.nossr50.util.skills.RankUtils;
|
2013-03-28 17:57:49 +01:00
|
|
|
import com.google.common.collect.ImmutableList;
|
2019-01-02 17:06:18 +01:00
|
|
|
import net.md_5.bungee.api.ChatColor;
|
|
|
|
import net.md_5.bungee.api.chat.TextComponent;
|
|
|
|
import org.bukkit.command.Command;
|
|
|
|
import org.bukkit.command.CommandExecutor;
|
|
|
|
import org.bukkit.command.CommandSender;
|
|
|
|
import org.bukkit.command.TabExecutor;
|
|
|
|
import org.bukkit.entity.Player;
|
2013-03-28 17:57:49 +01:00
|
|
|
|
2019-01-15 07:11:58 +01:00
|
|
|
import java.text.DecimalFormat;
|
2019-01-17 20:44:01 +01:00
|
|
|
import java.util.ArrayList;
|
2019-01-15 07:11:58 +01:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2013-03-28 17:57:49 +01:00
|
|
|
public abstract class SkillCommand implements TabExecutor {
|
2019-01-13 08:54:53 +01:00
|
|
|
protected PrimarySkillType skill;
|
2013-10-29 20:38:20 +01:00
|
|
|
private String skillName;
|
2013-03-01 06:52:01 +01:00
|
|
|
|
|
|
|
protected DecimalFormat percent = new DecimalFormat("##0.00%");
|
|
|
|
protected DecimalFormat decimal = new DecimalFormat("##0.00");
|
|
|
|
|
2013-03-12 21:25:42 +01:00
|
|
|
private CommandExecutor skillGuideCommand;
|
|
|
|
|
2019-01-13 08:54:53 +01:00
|
|
|
public SkillCommand(PrimarySkillType skill) {
|
2013-03-01 06:52:01 +01:00
|
|
|
this.skill = skill;
|
2013-10-28 18:04:06 +01:00
|
|
|
skillName = skill.getName();
|
2013-03-12 21:25:42 +01:00
|
|
|
skillGuideCommand = new SkillGuideCommand(skill);
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
|
|
|
if (CommandUtils.noConsoleUsage(sender)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-08-20 06:23:19 +02:00
|
|
|
if (!CommandUtils.hasPlayerDataKey(sender)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-03-12 21:25:42 +01:00
|
|
|
switch (args.length) {
|
|
|
|
case 0:
|
2013-10-29 20:38:20 +01:00
|
|
|
Player player = (Player) sender;
|
|
|
|
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
boolean isLucky = Permissions.lucky(player, skill);
|
|
|
|
boolean hasEndurance = (PerksUtils.handleActivationPerks(player, 0, 0) != 0);
|
|
|
|
float skillValue = mcMMOPlayer.getSkillLevel(skill);
|
|
|
|
|
|
|
|
permissionsCheck(player);
|
|
|
|
dataCalculations(player, skillValue, isLucky);
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2019-01-04 16:58:39 +01:00
|
|
|
sendSkillCommandHeader(player, mcMMOPlayer, (int) skillValue);
|
2013-03-08 14:39:28 +01:00
|
|
|
|
2019-01-04 16:58:39 +01:00
|
|
|
//Make JSON text components
|
|
|
|
List<TextComponent> subskillTextComponents = getTextComponents(player);
|
2013-03-08 14:39:28 +01:00
|
|
|
|
2019-01-04 16:58:39 +01:00
|
|
|
//Subskills Header
|
2019-01-09 04:52:52 +01:00
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Overhaul.Header", LocaleLoader.getString("Effects.SubSkills.Overhaul")));
|
2019-01-02 17:06:18 +01:00
|
|
|
|
2019-01-04 16:58:39 +01:00
|
|
|
//Send JSON text components
|
2019-01-09 04:52:52 +01:00
|
|
|
|
|
|
|
TextComponentFactory.sendPlayerSubSkillList(player, subskillTextComponents);
|
|
|
|
|
|
|
|
/*for(TextComponent tc : subskillTextComponents)
|
2019-01-04 16:58:39 +01:00
|
|
|
{
|
|
|
|
player.spigot().sendMessage(new TextComponent[]{tc, new TextComponent(": TESTING")});
|
2019-01-09 04:52:52 +01:00
|
|
|
}*/
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2019-01-04 16:58:39 +01:00
|
|
|
//Stats
|
|
|
|
getStatMessages(player, isLucky, hasEndurance, skillValue);
|
|
|
|
|
2019-01-09 04:52:52 +01:00
|
|
|
//Header
|
2019-01-17 19:45:16 +01:00
|
|
|
player.sendMessage(LocaleLoader.getString("Overhaul.mcMMO.Header"));
|
|
|
|
|
2019-01-09 04:52:52 +01:00
|
|
|
//Link Header
|
|
|
|
TextComponentFactory.sendPlayerUrlHeader(player);
|
|
|
|
|
2019-01-17 19:45:16 +01:00
|
|
|
if (Config.getInstance().getSkillUseBoard()) {
|
|
|
|
ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
|
|
|
|
}
|
2019-01-02 17:06:18 +01:00
|
|
|
|
2019-01-17 19:45:16 +01:00
|
|
|
return true;
|
2019-01-02 17:06:18 +01:00
|
|
|
default:
|
|
|
|
return skillGuideCommand.onCommand(sender, command, label, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void getStatMessages(Player player, boolean isLucky, boolean hasEndurance, float skillValue) {
|
|
|
|
List<String> statsMessages = statsDisplay(player, skillValue, hasEndurance, isLucky);
|
2013-10-29 20:38:20 +01:00
|
|
|
|
2019-01-02 17:06:18 +01:00
|
|
|
if (!statsMessages.isEmpty()) {
|
2019-01-09 04:52:52 +01:00
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Overhaul.Header", LocaleLoader.getString("Commands.Stats.Self.Overhaul")));
|
2013-10-29 20:38:20 +01:00
|
|
|
|
2019-01-02 17:06:18 +01:00
|
|
|
for (String message : statsMessages) {
|
|
|
|
player.sendMessage(message);
|
|
|
|
}
|
|
|
|
}
|
2013-10-29 20:38:20 +01:00
|
|
|
|
2019-01-02 17:06:18 +01:00
|
|
|
player.sendMessage(LocaleLoader.getString("Guides.Available", skillName, skillName.toLowerCase()));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendSkillCommandHeader(Player player, McMMOPlayer mcMMOPlayer, int skillValue) {
|
2019-01-13 07:41:06 +01:00
|
|
|
ChatColor hd1 = ChatColor.DARK_AQUA;
|
|
|
|
ChatColor c1 = ChatColor.GOLD;
|
|
|
|
ChatColor c2 = ChatColor.RED;
|
2019-01-09 04:52:52 +01:00
|
|
|
|
|
|
|
|
2019-01-13 07:41:06 +01:00
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Overhaul.Header", skillName));
|
2019-01-09 04:52:52 +01:00
|
|
|
|
2019-01-13 07:41:06 +01:00
|
|
|
if(!skill.isChildSkill())
|
|
|
|
{
|
2019-01-17 20:44:01 +01:00
|
|
|
/*
|
|
|
|
* NON-CHILD SKILLS
|
|
|
|
*/
|
|
|
|
|
2019-01-09 04:52:52 +01:00
|
|
|
//XP GAIN METHOD
|
|
|
|
player.sendMessage(LocaleLoader.getString("Commands.XPGain.Overhaul", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
|
|
|
|
|
|
|
|
//LEVEL
|
|
|
|
player.sendMessage(LocaleLoader.getString("Effects.Level.Overhaul", skillValue, mcMMOPlayer.getSkillXpLevel(skill), mcMMOPlayer.getXpToLevel(skill)));
|
|
|
|
|
|
|
|
} else {
|
2019-01-17 20:44:01 +01:00
|
|
|
/*
|
|
|
|
* CHILD SKILLS
|
|
|
|
*/
|
2019-01-09 04:52:52 +01:00
|
|
|
|
|
|
|
|
2019-01-13 08:54:53 +01:00
|
|
|
Set<PrimarySkillType> parents = FamilyTree.getParents(skill);
|
2019-01-17 20:44:01 +01:00
|
|
|
ArrayList<PrimarySkillType> parentList = new ArrayList<>();
|
2019-01-09 04:52:52 +01:00
|
|
|
|
2019-01-13 07:41:06 +01:00
|
|
|
//TODO: Add JSON here
|
2019-01-13 08:54:53 +01:00
|
|
|
for (PrimarySkillType parent : parents) {
|
2019-01-17 20:44:01 +01:00
|
|
|
parentList.add(parent);
|
|
|
|
/*player.sendMessage(parent.getName() + " - " + LocaleLoader.getString("Effects.Level.Overhaul", mcMMOPlayer.getSkillLevel(parent), mcMMOPlayer.getSkillXpLevel(parent), mcMMOPlayer.getXpToLevel(parent)))*/;
|
2019-01-13 07:41:06 +01:00
|
|
|
}
|
2019-01-17 20:44:01 +01:00
|
|
|
|
|
|
|
String parentMessage = "";
|
|
|
|
|
|
|
|
for(int i = 0; i < parentList.size(); i++)
|
|
|
|
{
|
|
|
|
if(i+1 < parentList.size())
|
|
|
|
{
|
|
|
|
parentMessage += LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i)));
|
|
|
|
parentMessage += ChatColor.GRAY+", ";
|
|
|
|
} else {
|
|
|
|
parentMessage += LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//XP GAIN METHOD
|
|
|
|
player.sendMessage(LocaleLoader.getString("Commands.XPGain.Overhaul", LocaleLoader.getString("Commands.XPGain.Child")));
|
|
|
|
|
|
|
|
player.sendMessage(LocaleLoader.getString("Effects.Child.Overhaul", skillValue, parentMessage));
|
|
|
|
//LEVEL
|
|
|
|
//player.sendMessage(LocaleLoader.getString("Effects.Child.Overhaul", skillValue, skillValue));
|
|
|
|
|
2019-01-13 07:41:06 +01:00
|
|
|
}
|
2019-01-09 04:52:52 +01:00
|
|
|
/*
|
2019-01-02 17:06:18 +01:00
|
|
|
if (!skill.isChildSkill()) {
|
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
|
|
|
|
player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
|
|
|
|
player.sendMessage(LocaleLoader.getString("Effects.Level", skillValue, mcMMOPlayer.getSkillXpLevel(skill), mcMMOPlayer.getXpToLevel(skill)));
|
|
|
|
} else {
|
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child")));
|
|
|
|
player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain.Child")));
|
|
|
|
player.sendMessage(LocaleLoader.getString("Effects.Child", skillValue));
|
|
|
|
|
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Skills.Parents")));
|
2019-01-13 08:54:53 +01:00
|
|
|
Set<PrimarySkillType> parents = FamilyTree.getParents(skill);
|
2019-01-02 17:06:18 +01:00
|
|
|
|
2019-01-13 08:54:53 +01:00
|
|
|
for (PrimarySkillType parent : parents) {
|
2019-01-02 17:06:18 +01:00
|
|
|
player.sendMessage(parent.getName() + " - " + LocaleLoader.getString("Effects.Level", mcMMOPlayer.getSkillLevel(parent), mcMMOPlayer.getSkillXpLevel(parent), mcMMOPlayer.getXpToLevel(parent)));
|
|
|
|
}
|
|
|
|
}
|
2019-01-09 04:52:52 +01:00
|
|
|
*/
|
2013-03-12 21:25:42 +01:00
|
|
|
}
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-03-28 17:57:49 +01:00
|
|
|
@Override
|
|
|
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
|
|
|
switch (args.length) {
|
|
|
|
case 1:
|
|
|
|
return ImmutableList.of("?");
|
|
|
|
default:
|
|
|
|
return ImmutableList.of();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected int calculateRank(float skillValue, int maxLevel, int rankChangeLevel) {
|
2013-03-12 21:25:42 +01:00
|
|
|
return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected String[] calculateAbilityDisplayValues(double chance, boolean isLucky) {
|
2013-03-12 21:25:42 +01:00
|
|
|
String[] displayValues = new String[2];
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-03-12 21:25:42 +01:00
|
|
|
displayValues[0] = percent.format(Math.min(chance, 100.0D) / 100.0D);
|
|
|
|
displayValues[1] = isLucky ? percent.format(Math.min(chance * 1.3333D, 100.0D) / 100.0D) : null;
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-03-12 21:25:42 +01:00
|
|
|
return displayValues;
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-09 04:52:52 +01:00
|
|
|
protected String[] calculateAbilityDisplayValues(float skillValue, SubSkillType subSkill, boolean isLucky) {
|
2018-12-29 14:24:55 +01:00
|
|
|
int maxBonusLevel = AdvancedConfig.getInstance().getMaxBonusLevel(subSkill);
|
2013-11-22 18:32:23 +01:00
|
|
|
|
2018-12-29 14:24:55 +01:00
|
|
|
return calculateAbilityDisplayValues((AdvancedConfig.getInstance().getMaxChance(subSkill) / maxBonusLevel) * Math.min(skillValue, maxBonusLevel), isLucky);
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected String[] calculateLengthDisplayValues(Player player, float skillValue) {
|
2013-09-15 19:47:20 +02:00
|
|
|
int maxLength = skill.getAbility().getMaxLength();
|
2019-01-13 09:31:58 +01:00
|
|
|
int abilityLengthVar = Config.getInstance().getIsRetroMode() ? AdvancedConfig.getInstance().getAbilityLengthRetro() : AdvancedConfig.getInstance().getAbilityLengthStandard();
|
|
|
|
int length = 2 + (int) (skillValue / abilityLengthVar);
|
2013-03-01 06:52:01 +01:00
|
|
|
int enduranceLength = PerksUtils.handleActivationPerks(player, length, maxLength);
|
|
|
|
|
|
|
|
if (maxLength != 0) {
|
2013-03-12 21:25:42 +01:00
|
|
|
length = Math.min(length, maxLength);
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return new String[] { String.valueOf(length), String.valueOf(enduranceLength) };
|
|
|
|
}
|
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected abstract void dataCalculations(Player player, float skillValue, boolean isLucky);
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected abstract void permissionsCheck(Player player);
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected abstract List<String> effectsDisplay();
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-10-29 20:38:20 +01:00
|
|
|
protected abstract List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky);
|
2019-01-02 17:06:18 +01:00
|
|
|
|
|
|
|
protected abstract List<TextComponent> getTextComponents(Player player);
|
2019-01-15 12:16:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if a player can use a skill
|
|
|
|
* @param player target player
|
|
|
|
* @param subSkillType target subskill
|
|
|
|
* @return true if the player has permission and has the skill unlocked
|
|
|
|
*/
|
|
|
|
protected boolean canUseSubskill(Player player, SubSkillType subSkillType)
|
|
|
|
{
|
|
|
|
return Permissions.isSubSkillEnabled(player, subSkillType) && RankUtils.hasUnlockedSubskill(player, subSkillType);
|
|
|
|
}
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|